gpt4 book ai didi

c++ - 从工作线程更新模态 QProgressDialog

转载 作者:行者123 更新时间:2023-11-28 04:44:00 24 4
gpt4 key购买 nike

我想从我的工作线程更新一个modal 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 循环,并使您的进度对话框成为您类(class)的成员。我也不太喜欢那个 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"

关于c++ - 从工作线程更新模态 QProgressDialog,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/49646235/

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