防止模式对话框中的事件循环阻塞
Prevent event loop blocking in modal dialog
我正在开发一个应用程序,用户可以在其中解析一些二进制文件。一旦他点击"解析"按钮,他首先可以选择一些文件,然后进行解析。当应用程序处理文件时,我想显示一个模式对话框,通知用户进度(QProgressBar 栏)和已解析的文件(QListView list/listModel)。
我目前的方法是覆盖QDialog-sublcass的exec()方法。这样我就可以打电话
parseAssistant.exec()
当前实现如下所示:
class ParseAssistant : public QDialog { public: int exec(); };
int ParseAssistant::exec()
{
bar->setMaximum(files.size());
this->show();
this->setModal(true);
for (int i = 0; i < files.size(); i++) {
PluginTable* table = parser.parse(files[i]);
// do something with the table
// saveTableintoDB();
// update GUI
// bar->setValue(i);
// listModel->insertRow(0, new QStandardItem(files[i]));
}
this->hide();
return QDialog::Accepted;
}
运行此(阻塞)方法后,用户已解析所有文件或在某处取消进度。为了实现这一点,我尝试在while循环中使用QApplication::p rocessEvents(感觉有点滞后,因为它只有在文件完成解析时才进行)或将繁重的计算外包给一些QConcurrent实现(::run,::mapped)。不幸的是,我不知道如何在 QFuture 完成后将程序流返回到 exec() 方法,而不依赖于一些 CPU 密集型循环,例如:
while (!future.isFinished()) { QApplication::processEvents(); }
是否有更智能的方法来运行繁重的计算(用户可能会取消)而不会阻塞事件循环?
我首先不会Qdialog
子类,而只是使用QFutureWatcher
并将观察器finished
信号连接到对话框close
插槽,这样:
QDialog d;
QFutureWatcher<void> watcher;
QObject::connect(&watcher, &QFutureWatcher<void>::finished, &d, &QDialog::close);
QFuture<void> future = QtConcurrent::run(your_parse_function);
watcher.setFuture(future);
d.exec();
//control returns here when your_parse_function exits
parse 函数可以是 QObject 派生类中的一个方法,如下所示:
class Parser : public QObject
{
Q_OBJECT
public:
void parse()
{
for (int i = 0; i < files.size(); i++) {
PluginTable* table = parser.parse(files[i]);
emit fileParsed(i, files.size);
// ...
}
}
signals:
void fileParsed(int id, int count);
};
您可以将fileParsed
信号连接到所选插槽,然后从那里相应地设置进度条值。
我个人的方法是:
- 创建一个单独的线程并在那里进行处理(QThread; std::thread也应该可以解决问题)
- 提供通知当前正在处理的文件的信号
- 可能是另一个信号,告知 % 的进展
- 另一个信号通知处理已完成,在线程结束之前发出
- 为您的对话提供适当的插槽并将它们连接到信号(因为涉及不同的线程,请确保连接类型
Qt::QueuedConnection
)
相关文章:
- 具有Qt事件循环的可移植通用共享库设置
- 如何将事件循环中的事件分派给订阅者?
- C++uWebSockets将事件循环集成到一个线程中
- 了解如何在不冻结事件循环的情况下在 QThread 中休眠/等待
- 如何在主事件循环之前创建一些对象?
- Libuv:保护事件循环免受并发访问
- 防止模式对话框中的事件循环阻塞
- QCoreApplication事件循环和Windows服务控制处理程序功能
- c++ 过期映射条目线程与事件循环
- Qt的事件循环线程是安全的还是原子的?处理"队列连接"时如何同步?
- 在事件循环启动后删除并创建新的 RTP 流
- QSTATEMACHINE事件循环与动画
- 等待事件循环为空 /等到QT5小部件关闭
- 如何将lambda函数排队到Qt的事件循环中?
- DLL中的QT事件循环
- 运行Qt 5.10事件循环howto的Windows服务service_WIN32_OWN_PROCESS
- 模态qprogressdialog :: setValue()导致嵌套事件循环崩溃
- 什么是QT中的事件循环
- Libuv中SD-BUS的事件循环处理
- Qt的事件循环是FIFO吗?