Stanton Stanton - 1 year ago 128
C++ Question

QTableWidget's cell widget not displaying correctly when last row deleted

I have a QTableWidget that has QPushButtons as cell widgets. I use these push buttons as a means to delete a row from the table. I'm having a problem where the QPushButtons can be accidentally shifted from being centered in their cell. The image below shows what is happening.

enter image description here

This occurs in the specific case where the user has 1) made selected a cell in the last row of the table, 2) that cell contains a delete button, and 3) the vertical scroll bar is moved such that the last row is partially visible.

Below is a very minimal example that will create this problem. The user needs to use the scrollbar and scroll up by one tick, then press the last delete button.

Edited to include clear selection before call to removeRow:

MainWindow::MainWindow(QWidget *parent) :
ui(new Ui::MainWindow),
signalMapper_(new QSignalMapper(this)),
table_(new QTableWidget())

QGridLayout *layout = new QGridLayout(ui->centralWidget);


// if you comment out the following line then the problem is not present

for (int i = 0; i < 20; i++) {
QPushButton *button = new QPushButton("Delete");
connect(button, SIGNAL(clicked(bool)), signalMapper_, SLOT(map()));
signalMapper_->setMapping(button, i);
table_->setCellWidget(i, 0, button);
connect(signalMapper_, SIGNAL(mapped(int)), this, SLOT(DeletePressed(int)));


delete ui;

void MainWindow::DeletePressed(int row)
table_->clearSelection(); // <- added clear selection before remove row

I think the problem stems from the QTableWidget trying to keep the selected cell visible when a new selection is made. I have tried both of the answers posted here but neither solved my problem.

If anyone could tell me how to solve this problem I would appreciate the help.

Answer Source

I had a similar problem a long time ago with a QtreeWidget and I solved it by callig protected method updateGeometries().

If you did not specialize QTableView, you can't simply call this function (as it is protected), so here's a trick to simply do it:

class MyQTableView : public QTableView
    inline void publicUpdateGeometries() { updateGeometries(); }

void MainWindow::DeletePressed(int row)
    table_->clearSelection(); // <- added clear selection before remove row

    // call the protected method QTableView::updateGeometries()
    ((MyQTableView*) table_)->publicUpdateGeometries();

Hope this will solve your problem.

Recommended from our users: Dynamic Network Monitoring from WhatsUp Gold from IPSwitch. Free Download