gpt4 book ai didi

c++ - QTableWidget:信号itemChanged触发得太晚了(在发出其他 Action 的信号,关闭等之后)

转载 作者:行者123 更新时间:2023-12-03 07:21:54 28 4
gpt4 key购买 nike

我正在使用QTableWidget表示一些用户可编辑的数据。编辑后,通过连接到表的itemChanged(QTableWidgetItem*)信号来更新数据的内部表示。
我有一个菜单操作“保存”,它保存数据,并且如果用户尝试关闭窗口,我还要检查closeEvent中是否修改了当前文档。如果用户在未保存修改的情况下尝试关闭,则会询问他们是否要保存。
现在的问题是,itemChanged信号似乎仅在表失去输入焦点时才发送。考虑这种情况:用户双击表中的一个单元格,更改文本,然后立即单击“保存”。在发送itemChanged信号之前,因此在实际同步用户输入之前,将触发save操作。同样,如果用户关闭窗口。
我尝试在save函数中主动从表中读取数据,而不是等待信号触发,但这也不起作用,因为在打开编辑器时,相应的项仍包含旧数据。
这显然是一个大问题,因为要么保存了错误的数据,要么根本没有保存,即数据丢失。
我该如何正确处理呢?

随附的是演示此问题的最小工作示例。出于演示目的,closeEvent仅无条件执行“保存”(仅在此处打印)。在实际的应用程序中,它将检查是否首先修改了数据,但修改不正确。
mainwindow.h:

#include <QMainWindow>
#include <QMenu>
#include <QMenuBar>
#include <QTableWidget>

#include <iostream>
#include <vector>

class MainWindow : public QMainWindow
{
Q_OBJECT

private:
std::vector<double> data;
QTableWidget* table;

public:
MainWindow(QWidget* parent = nullptr) : QMainWindow(parent)
{
data = {1.0, 2.0, 3.0};
table = new QTableWidget(this);
table->setRowCount(1);
table->setColumnCount(data.size());
for (size_t i = 0; i < data.size(); i++)
table->setItem(0, i, new QTableWidgetItem(QString::number(data[i])));
connect(table, SIGNAL(itemChanged(QTableWidgetItem*)),
SLOT(on_table_itemChanged(QTableWidgetItem*)));
setCentralWidget(table);

QMenuBar* menubar = new QMenuBar(this);
QMenu* file = new QMenu("File", menubar);
QAction* save = new QAction("Save", this);
file->addAction(save);
menubar->addMenu(file);
setMenuBar(menubar);
connect(save, SIGNAL(triggered()), SLOT(on_actionSave_triggered()));
setGeometry(0, 0, 400, 100);
}

private slots:
void on_actionSave_triggered()
{
std::cout << "data: " << data[0] << ", " << data[1] << ", " << data[2] << std::endl;
std::cout << "item 0: " << table->item(0, 0)->text().toDouble()
<< ", item 1: " << table->item(0, 1)->text().toDouble()
<< ", item 2: " << table->item(0, 2)->text().toDouble() << std::endl;
}
void on_table_itemChanged(QTableWidgetItem* item)
{
data[item->column()] = item->text().toDouble();
}
};
main.cpp:
#include "mainwindow.h"
#include <QApplication>

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

最佳答案

对于您的情况,在触发保存操作时,您可以首先将焦点设置为QTableWidget对象。编辑器将失去焦点并提交数据。我认为这比我在评论中建议的方法更好(因为它假定编辑器是QLineEdit对象,并使用dynamic_cast)。

#include "mainwindow.h"

#include <QDebug>
#include <QDialog>
#include <QMenuBar>
#include <QPushButton>
#include <QTableWidget>
#include <QVBoxLayout>

MainWindow::MainWindow(QWidget *parent)
: QMainWindow(parent)
{
QTableWidget *table_widget = new QTableWidget{this};
table_widget->setRowCount(1);
table_widget->setColumnCount(1);
table_widget->setItem(0, 0, new QTableWidgetItem(QString{"Some text"}));
connect(table_widget, &QTableWidget::itemChanged, [](){qDebug() << "Item changed";});

QDialog *dialog = new QDialog{this};
connect(dialog, &QDialog::accepted, [](){qDebug() << "Dialog accepted";});
connect(dialog, &QDialog::rejected, [](){qDebug() << "Dialog rejected";});

QMenuBar *menu_bar = new QMenuBar(this);
QMenu *file_menu = new QMenu("File", menu_bar);
QAction *save_action = new QAction("Save", this);
file_menu->addAction(save_action);
menu_bar->addMenu(file_menu);
connect(save_action, &QAction::triggered, table_widget, QOverload<>::of(&QWidget::setFocus));
connect(save_action, &QAction::triggered, [=](){qDebug() << "Save triggered";});

QPushButton *save_button = new QPushButton{"Save", this};
connect(save_button, &QPushButton::clicked, [](){qDebug() << "Save clicked";});
QVBoxLayout *layout = new QVBoxLayout{dialog};
layout->addWidget(menu_bar);
layout->addWidget(table_widget);
layout->addWidget(save_button);

QPushButton *open_button = new QPushButton{"Open dialog", this};
connect(open_button, &QPushButton::clicked, dialog, &QDialog::show);
this->setCentralWidget(open_button);
}

MainWindow::~MainWindow()
{
}
我还注意到,如果使用按钮保存数据,焦点将自动更改为按钮,从而导致相同的行为。我猜想用 QToolBarQToolButton代替 QMenuBar也可以工作。

关于c++ - QTableWidget:信号itemChanged触发得太晚了(在发出其他 Action 的信号,关闭等之后),我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/64860514/

28 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com