[英]QtConcurrent::map crashes if no QProgressDialog is shown
考虑一下在我的主线程中的这个SLOT
,由一个按钮触发,该按钮从QTreeWidgetItem
获取QTreeWidget
的列表。 它使用QtConcurrent::map()
调用执行一个长任务。 watcher
连接到QProgressDialog
以显示进度。
void Main::on_actionButton_triggered() {
qRegisterMetaType<QVector<int> >("QVector<int>");
//Setting up a progress dialog
QProgressDialog progressDialog;
//Holds the list
QList<QTreeWidgetItem*> list;
//Setup watcher
QFutureWatcher<void> watcher;
//Setting up connections
//Progress dialog
connect(&watcher, SIGNAL(progressValueChanged(int)), &progressDialog, SLOT(setValue(int)));
connect(&watcher, SIGNAL(progressRangeChanged(int, int)), &progressDialog, SLOT(setRange(int,int)));
connect(&watcher, SIGNAL(progressValueChanged(int)), ui->progressBar, SLOT(setValue(int)));
connect(&watcher, SIGNAL(progressRangeChanged(int, int)), ui->progressBar, SLOT(setRange(int,int)));
connect(&watcher, SIGNAL(finished()), &progressDialog, SLOT(reset()));
connect(&progressDialog, SIGNAL(canceled()), &watcher, SLOT(cancel()));
connect(&watcher, SIGNAL(started()), this, SLOT(processStarted()));
connect(&watcher, SIGNAL(finished()), this, SLOT(processFinished()));
//Gets the list filled
for (int i = 0; i < ui->listTreeWidget->topLevelItemCount(); i++) {
list.append(ui->listTreeWidget->topLevelItem(i));
}
//And start
watcher.setFuture(QtConcurrent::map(list, processRoutine));
//Show the dialog
progressDialog.exec();
}
extern void processRoutine(QTreeWidgetItem* item) {
qDebug() << item->text(4);
}
我还在UI(包含所有先前的小部件)中添加了具有相同SIGNALS / SLOTS的QProgressBar
。 使代码像以前一样正常工作:将显示进度对话框,并且进度栏将完全按照对话框进行更新。 相反,如果我评论
//progressDialog.exec();
或我以某种方式隐藏对话框,该过程将崩溃(并非总是如此,有时进展顺利)。 看qDebug() << item->text(4);
崩溃,输出显示随机混合的文本(它们应该是文件名)。 此外,即使未崩溃,即使未显示QProgressDialog
时,进度QProgressDialog
也不会自动更新。
注意:我之前在另一个函数中遇到过类似的问题,我通过设置解决了
QThreadPool::globalInstance()->setMaxThreadCount(1);
仅在Windows上,OSX可以。
那么, QProgressDialog
背后使所有事情正确的诀窍是什么? 有没有一种方法可以使用QProgressBar
而不是QProgressDialog
?
注意
这是该过程顺利完成时的输出:
"C:/Users/Utente/Pictures/Originals/unsplash_52cee67a5c618_1.jpg"
"C:/Users/Utente/Pictures/Originals/photo-1428278953961-a8bc45e05f72.jpg"
"C:/Users/Utente/Pictures/Originals/photo-1429152937938-07b5f2828cdd.jpg"
"C:/Users/Utente/Pictures/Originals/photo-1429277158984-614d155e0017.jpg"
"C:/Users/Utente/Pictures/Originals/photo-1430598825529-927d770c194f.jpg"
"C:/Users/Utente/Pictures/Originals/photo-1433838552652-f9a46b332c40.jpg"
当您注释progressDialog.exec();
您的on_actionButton_triggered()
函数以破坏progressDialog
on_actionButton_triggered()
,因此您的信号使用了无处指向的指针。 同样,在执行所有映射之前或之后, watcher
也将被销毁,并且公平地说,它不会停止线程,因此它们也无处工作。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.