han*_*dle 2 user-interface qt multithreading
我正在使用QThread MyObject->moveToThread(myThread);来进行需要一段时间的通信功能.一些信号和插槽保持GUI发布有关进度.
但是,在需要用户交互的线程通信期间可能会出现某些情况 - 因为无法在线程内创建QMessageBox,我想发出一个信号,允许我暂停线程并显示对话框.但首先,似乎没有办法暂停一个线程,其次,这种尝试可能会失败,因为它需要一种方法在恢复时将参数传递回线程.
一个不同的方法可能是事先将所有参数传递给线程,但这可能不是一个选项.
这通常是怎么做的?
编辑
感谢#1的评论,并希望得到我的希望,但请详细说明如何从线程中的对象创建例如对话框以及如何暂停它.
使用Qt 4.8.1和MSVC++ 2010的以下示例代码导致:
MyClass::MyClass created
MainWindow::MainWindow thread started
MyClass::start run
ASSERT failure in QWidget: "Widgets must be created in the GUI thread.", file kernel\qwidget.cpp, line 1299
Run Code Online (Sandbox Code Playgroud)
mainwindow.h
#ifndef MAINWINDOW_H
#define MAINWINDOW_H
#include <QMainWindow>
namespace Ui {
class MainWindow;
}
class MainWindow : public QMainWindow
{
Q_OBJECT
public:
explicit MainWindow(QWidget *parent = 0);
~MainWindow();
private:
Ui::MainWindow *ui;
};
#endif // MAINWINDOW_H
Run Code Online (Sandbox Code Playgroud)
mainwindow.cpp
#include "mainwindow.h"
#include "ui_mainwindow.h"
#include "myclass.h"
#include <QThread>
#include <QDebug>
MainWindow::MainWindow(QWidget *parent) :
QMainWindow(parent),
ui(new Ui::MainWindow)
{
ui->setupUi(this);
QThread *thread = new QThread();
MyClass* myObject = new MyClass();
myObject->moveToThread( thread );
connect(thread, SIGNAL( started()), myObject, SLOT(start()));
connect(myObject, SIGNAL( finished()), thread, SLOT(quit()));
connect(myObject, SIGNAL( finished()), myObject, SLOT(deleteLater()));
connect(thread, SIGNAL( finished()), thread, SLOT(deleteLater()));
thread->start();
if( thread->isRunning() )
{
qDebug() << __FUNCTION__ << "thread started";
}
}
MainWindow::~MainWindow()
{
delete ui;
}
Run Code Online (Sandbox Code Playgroud)
myclass.h
#ifndef MYCLASS_H
#define MYCLASS_H
#include <QObject>
class MyClass : public QObject
{
Q_OBJECT
public:
explicit MyClass(QObject *parent = 0);
signals:
void finished();
public slots:
void start();
};
#endif // MYCLASS_H
Run Code Online (Sandbox Code Playgroud)
myclass.cpp
#include "myclass.h"
#include <QMessageBox>
#include <QDebug>
MyClass::MyClass(QObject *parent) :
QObject(parent)
{
qDebug() << __FUNCTION__ << "created";
}
void MyClass::start()
{
qDebug() << __FUNCTION__ << "run";
// do stuff ...
// get information from user (blocking)
QMessageBox *msgBox = new QMessageBox();
msgBox->setWindowTitle( tr("WindowTitle") );
msgBox->setText( tr("Text") );
msgBox->setInformativeText( tr("InformativeText") );
msgBox->setStandardButtons( QMessageBox::Ok | QMessageBox::Cancel);
msgBox->setDefaultButton( QMessageBox::Ok);
msgBox->setEscapeButton( QMessageBox::Cancel);
msgBox->setIcon( QMessageBox::Information);
int ret = msgBox->exec();
// continue doing stuff (based on user input) ...
switch (ret)
{
case QMessageBox::Ok:
break;
case QMessageBox::Cancel:
break;
default:
break;
}
// do even more stuff
emit finished();
}
Run Code Online (Sandbox Code Playgroud)
在信号/槽连接中使用Qt :: BlockingQueuedConnection(对QObject :: connect()的调用).
http://doc.qt.digia.com/qt/qt.html#ConnectionType-enum
这将阻止您的线程,直到UI线程上的插槽返回,然后UI线程中的插槽可以自由显示消息框/模式对话框/无论您想要做什么.
您必须确保您的工作线程实际上不在UI线程上,因为正如文档所说,如果信号和插槽位于同一线程上,这将导致死锁(因为它将阻塞自身).