gpt4 book ai didi

multithreading - Qt GUI 用户与 QThread 对象中的 QMessageBox 交互

转载 作者:行者123 更新时间:2023-12-03 23:53:11 24 4
gpt4 key购买 nike

我将 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

主窗口.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

主窗口.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;
}

我的类.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

我的类.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();
}

最佳答案

在信号/槽连接中使用 Qt::BlockingQueuedConnection(调用 QObject::connect())。

http://doc.qt.digia.com/qt/qt.html#ConnectionType-enum

这将阻塞您的线程,直到 UI 线程上的槽返回,然后 UI 线程中的槽可以自由显示消息框/模态对话框/任何您想做的事情。

必须确保您的工作线程实际上不在 UI 线程上,因为正如文档所说,如果信号和插槽在同一个线程上(因为它将阻止自己)。

关于multithreading - Qt GUI 用户与 QThread 对象中的 QMessageBox 交互,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/13933591/

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