2

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.

jpo38
  • 20,821
  • 10
  • 70
  • 151
Stanton
  • 904
  • 10
  • 25

3 Answers3

1

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.

jpo38
  • 20,821
  • 10
  • 70
  • 151
0

Try ui->tableWidget->clearSelection();

Szymson
  • 990
  • 1
  • 13
  • 28
  • Where should I place this in my code? I made a slot called `DeletePressed(int row)` which I connected to the signalMapper. In the slot I added your `clearSelection()` followed by the `removeRow(row)` call, but that didn't solve the problem. – Stanton Nov 18 '15 at 14:38
  • I think you should call `clearSelection` before `removeRow(row)` – Szymson Nov 19 '15 at 11:45
  • I've made the change as you suggested, but this didn't solve my problem. Please see the edited code above to see that I did this as you intended. – Stanton Nov 19 '15 at 14:39
0

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.