2
votes

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.

mainwindow.h:

#pragma once

#include <QMainWindow>

class QSignalMapper;
class QTableWidget;
class MainWindow : public QMainWindow
{
    Q_OBJECT

public:
    explicit MainWindow(QWidget *parent = 0);
    ~MainWindow();

public slots:
    void DeletePressed(int row);

private:
    QSignalMapper* signalMapper_;
    QTableWidget* table_;
};

mainwindow.cpp:

#include "mainwindow.h"

#include <QGridLayout>
#include <QSignalMapper>
#include <QTableWidget>
#include <QPushButton>

MainWindow::MainWindow(QWidget *parent) :
    QMainWindow(parent),
    signalMapper_(new QSignalMapper(this)),
    table_(new QTableWidget())
{
    setCentralWidget( new QWidget );
    this->setFixedSize(200,300);

    QGridLayout *layout = new QGridLayout(centralWidget());
    layout->addWidget(table_);

    table_->setRowCount(0);
    table_->setColumnCount(1);

    // if you comment out the following line then the problem is not present
    table_->setSelectionMode(QAbstractItemView::SingleSelection);

    for (int i = 0; i < 20; i++) {
        table_->insertRow(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)));

    table_->setCurrentCell(19,0);
}

MainWindow::~MainWindow()
{
}

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

main.cpp:

#include <QApplication>
#include "mainwindow.h"

int main( int argc, char* argv[] )
{
    QApplication app(argc, argv);
    MainWindow wnd;
    wnd.show();
    return app.exec();
}

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.

3

3 Answers

1
votes

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
{
public:
    inline void publicUpdateGeometries() { updateGeometries(); }
};

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

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

Hope this will solve your problem.

0
votes

Try ui->tableWidget->clearSelection();

0
votes

This happen only when scroll bar is added.to solve this you need to setvrticalscrollbarpolicy to scroll bar off then delete the row and add the scroll as needed by setverticalbarpolicy. It will solve your problem. I did the same way.