删除最后一行时,QTableWidget 的单元格小部件无法正确显示

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

我有一个 QTableWidget,它以 QPushButtons 作为单元格小部件。我使用这些按钮作为从 table 中删除一行的方法。我遇到了一个问题,QPushButtons 可能会意外地从它们的单元格中移动。下图显示了正在发生的事情。

这发生在以下特定情况下:用户 1) 在 table 的最后一行中选择了一个单元格,2) 该单元格包含一个删除按钮,以及 3) 垂直滚动条是移动到最后一行部分可见。

下面是一个会产生此问题的非常小的示例。用户需要使用滚动条向上滚动一个tick,然后按下最后一个删除按钮。

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();
}

我认为问题源于 QTableWidget 在进行新选择时试图保持所选单元格可见。我已经尝试了 here 发布的两个答案,但都没有解决我的问题。

如果有人能告诉我如何解决这个问题,我将不胜感激。

尝试ui->tableWidget->clearSelection();

我很久以前遇到过类似的问题QtreeWidget,我通过调用受保护的方法解决了它updateGeometries()

如果你没有专门化QTableView,你不能简单地调用这个函数(因为它是受保护的),所以这里有一个简单的技巧:

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();
}

希望这能解决您的问题。

仅当滚动条为 added.to 时才会发生这种情况解决此问题您需要设置 vrticalscrollbarpolicy 以关闭滚动条,然后删除该行并根据需要通过 setverticalbarpolicy 添加滚动条。 它会解决你的问题。 我也是这样做的。