Modal QprogressDialog从Worker线程更新
Modal QProgressDialog updated from worker thread
我想从我的工作线程中更新模态 qprogressdialog。但是,如果我将对话框设置为模态,我的应用程序会崩溃(对话框没有显示任何进度(。如果我不这样做,一切都很好(但是用户可以修改程序的其余部分,这可能会导致问题(。
。我在做什么错?
最低代码样本如下:
filereader qfr;
QProgressDialog progress("Importing file.", "Cancel", 0, file_size);
connect(&qfr, &filereader::signalProgress, &progress, &QProgressDialog::setValue, Qt::QueuedConnection);
QThread worker_thread;
std::atomic<bool> success = false;
connect(&worker_thread, &QThread::started,
[&]() {
success = qfr.read_file(/* parameters */);
worker_thread.quit();});
worker_thread.start();
//progress.setWindowModality(Qt::WindowModal); // Works only fine when this line is commented !!
while (worker_thread.isRunning()) {
QApplication::processEvents();
QThread::sleep(0);
}
progress.close();
您的线程几乎毫无意义。它没有真正的目的。您也可以在read_file
方法中刚刚称为QApplication::processEvents
。但是您不应该,打电话给processEvents
是不好的练习。
您应该做的是删除该 while
循环,并使您的进度对话成为班级的成员。我也不喜欢那个Lambda的样子。我个人只会将filereader::read_file
用作插槽。
请注意,Qt::windowModal
将输入输入到父窗口。您的进度对话框没有父母。因此,您要么必须致电progress->setModal(true)
或progress.setWindowModality(Qt::ApplicationModal);
。或设置父母。
这是一个很小的例子(不是为您的应用程序量身定制,但它应该指向正确的方向(:
#include <QtWidgets>
class Worker : public QObject
{
Q_OBJECT
public:
Worker(QObject *parent = nullptr) : QObject(parent){}
public slots:
void simulateLongProcess()
{
for(int i = 0; i < 101; i++)
{
emit progressChanged(i);
QThread::msleep(100);
}
emit finishedWorking(true);
}
signals:
void progressChanged(int progress);
void finishedWorking(bool result);
};
class Widget : public QWidget
{
Q_OBJECT
public:
Widget(QWidget *parent = nullptr) : QWidget(parent)
{
setLayout(new QHBoxLayout);
progress_dialog.setModal(true);
progress_dialog.setAutoReset(false);
progress_dialog.setCancelButton(nullptr);
QThread *thread = new QThread(this);
connect(thread, &QThread::started, &worker, &Worker::simulateLongProcess);
connect(&worker, &Worker::finishedWorking, thread, &QThread::quit);
connect(&worker, &Worker::progressChanged, &progress_dialog, &QProgressDialog::setValue);
connect(&worker, &Worker::finishedWorking, &progress_dialog, &QProgressDialog::close);
connect(&worker, &Worker::finishedWorking, this, &Widget::handleResult);
QPushButton * start_button = new QPushButton("START");
connect(start_button, &QPushButton::clicked, this, [=]
{
progress_dialog.show();
thread->start();
});
layout()->addWidget(start_button);
resize(400, 300);
}
public slots:
void handleResult(bool result)
{
// do something with the result
}
private:
QProgressDialog progress_dialog;
Worker worker;
};
int main(int argc, char *argv[])
{
QApplication a(argc, argv);
Widget w;
w.show();
return a.exec();
}
#include "main.moc"
相关文章:
- 发出信号以从线程更新 UI
- 为什么 beginthreadex 线程参数变量在父线程中没有更新
- Modal QprogressDialog从Worker线程更新
- 从另一个线程更新QT小部件的一种详细方法
- 从其他std ::线程更新QT GUI
- 从工作线程更新QtCharts的正确方法
- C++从异步线程更新窗口
- 线程更新全局指针时对全局指针的影响
- 从其他线程更新QT图形视图
- 从线程更新进度条的最佳方式
- 如何允许工作线程更新 X11 窗口
- Gtkmm : 如何从另一个线程更新 UI?不断
- 从多个线程更新命令行 printf 信息
- 如何从未创建该窗口的线程更新该窗口
- 按线程更新 QT
- 如何从另一个线程更新列表视图
- 从聚合线程更新QListView会使GUI卡住
- 从不同的线程更新GUI
- 从运行QML QtQuick2引擎的不同线程更新c++模型的行为
- 线程更新类对象