Bad*_*ild 5 c++ user-interface qt multithreading
我将保持代码简单,以便你们可以看到我正在尝试做什么;)我知道所有的锁定问题,等等.我正在试图弄清楚信号和插槽如何与线程一起玩.
在main.cpp中:
int main(int argc, char *argv[]) {
QApplication app(argc, argv);
MyConsole c; // Subclasses QThread and implements run()
MyReceiver r(app); // We pass app to MyReceiver for later (see below)
QObject::connect(&c, SIGNAL(sendit()),
&r, SLOT(gotit()));
c.start(); // Start the worker thread
app.exec();
}
Run Code Online (Sandbox Code Playgroud)
假设信号和插槽已在头文件中正确设置(我已经测试过它们).现在,问题在于:
在MyReceiver.cpp中:
void MyReceiver::gotit()
{
QLabel *label = new QLabel(0, "Hello"); // Some GUI element, any will do
app.setMainWidget(*label); // Some GUI action, any will do
}
Run Code Online (Sandbox Code Playgroud)
问题是:因为MyReceiver对象是在main()中创建的,它位于主线程上,这是否意味着插槽(例如,gotit())将在主线程上运行,因此可以安全地执行GUI操作?即使在信号是从不同的QThread(如本例中的MyConsole)中引发的情况下?
是否有更好的方法允许工作线程与GUI交互(例如,Obj-C/Cocoa有一个"主线程上的发送消息"类型的方法).这样做的"Qt方式"是什么?
提前致谢!
默认情况下(Qt :: AutoConnection),插槽将在创建QObject的线程中运行.因此,无论从哪个线程发出信号,插槽都将始终在线程中运行,QObject"生活"在(如果Qt事件循环在该线程中运行,否则无法传递事件).由于主线程将成为Qt GUI线程,这将按预期工作.这确实是与GUI交互的Qt方式.另请参阅:http://doc.qt.nokia.com/4.7/thread-basics.html(查找线程关联性).
从一个线程发出信号并在不同线程中接收信号的“Qt 方式”是使用排队连接
connect( obj, SIGNAL(foo()), other_obj, SLOT(bar()), Qt::QueuedConnection )
Run Code Online (Sandbox Code Playgroud)
来自 Qt::QueuedConnection 的 Qt 文档:
当控制返回到接收者线程的事件循环时,将调用该槽。该槽在接收者的线程中执行。