C++ 如何在不同的 QT 线程中创建窗口?
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/9777911/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
How do I create a Window in different QT threads?
提问by chacham15
I have an application in which each thread (except the main thread) needs to create its own window. I tried creating a thread and then calling this->exec()
in the run
function. However, I get an error before I even get to that call: ASSERT failure in QWidget: "Widgets must be created in the GUI thread."
我有一个应用程序,其中每个线程(主线程除外)都需要创建自己的窗口。我尝试创建一个线程,然后调用this->exec()
该run
函数。但是,在我接到那个电话之前,我收到了一个错误:ASSERT failure in QWidget: "Widgets must be created in the GUI thread."
I want to popup a message window. The problem is that the source has multiple threads each of which may need to popup its own message.
我想弹出一个消息窗口。问题是源有多个线程,每个线程可能需要弹出自己的消息。
回答by aleksey_m_t
If you need to create QWidget(or some other gui component(s)) in different(non-main) thread(s) you can implement it in such way:
如果您需要在不同的(非主)线程中创建 QWidget(或其他一些 gui 组件),您可以通过以下方式实现它:
Create simple wrapper which holds gui component:
// gui component holder which will be moved to main thread class gui_launcher : public QObject { QWidget *w; // other components //.. public: virtual bool event( QEvent *ev ) { if( ev->type() == QEvent::User ) { w = new QWidget; w->show(); return true; } return false; } };
create QApplication object in main thread
another thread body:
.. // create holder gui_launcher gl; // move it to main thread gl.moveToThread( QApplication::instance()->thread() ); // send it event which will be posted from main thread QCoreApplication::postEvent( &gl, new QEvent( QEvent::User ) ); ..
be happy, :)
创建包含 gui 组件的简单包装器:
// gui component holder which will be moved to main thread class gui_launcher : public QObject { QWidget *w; // other components //.. public: virtual bool event( QEvent *ev ) { if( ev->type() == QEvent::User ) { w = new QWidget; w->show(); return true; } return false; } };
在主线程中创建 QApplication 对象
另一个线程体:
.. // create holder gui_launcher gl; // move it to main thread gl.moveToThread( QApplication::instance()->thread() ); // send it event which will be posted from main thread QCoreApplication::postEvent( &gl, new QEvent( QEvent::User ) ); ..
要开心, :)
回答by spbots
Qt will only let you create GUI elements in the GUI thread - what is it that you need to display from the other threads? See something like This answerfor an example of updating a progress bar with data from a non-GUI thread.
Qt 只会让您在 GUI 线程中创建 GUI 元素 - 您需要从其他线程显示什么?有关使用来自非 GUI 线程的数据更新进度条的示例,请参阅类似此答案的内容。
Update:
更新:
If you want to show a message for each window, you can have a class like this:
如果你想为每个窗口显示一条消息,你可以有一个这样的类:
class MyWorkerThread : public QThread
{
Q_OBJECT
signals:
void sendMessage(QString msg);
private:
void run()
{
/* do stuff */
emit sendMessage(QString("This thread is doing stuff!"));
/* do more stuff */
}
};
Then connect it up to your GUI via the signal-slot mechanism with something like:
然后通过信号槽机制将其连接到您的 GUI,例如:
connect(workerThread, SIGNAL(sendMessage(QString)),
guiController, SLOT(showMessageBox(QString)));
Where the showMessageBox
function does what you need it to do.
showMessageBox
函数在哪里执行您需要它执行的操作。
回答by Tom Kerr
I don't believe this is possible. Other non-GUI components can run in other threads and will usually communicate via the signal/slot mechanisms.
我不相信这是可能的。其他非 GUI 组件可以在其他线程中运行,并且通常通过信号/插槽机制进行通信。
回答by Massood Khaari
The above answers can be combined with a QAction
object (or custom class objects) to transfer any action to the main GUI thread to be executed, not just creating widgets or displaying a message box. (e.g. by emitting sendAction(QAction*)
, or implementing a custom QEvent
class embodying a QAction*
.)
上述答案可以与QAction
对象(或自定义类对象)结合,以将任何操作转移到要执行的主 GUI 线程,而不仅仅是创建小部件或显示消息框。(例如,通过发出sendAction(QAction*)
,或实现一个QEvent
包含QAction*
.的自定义类。)