我会保持代码简单,以便你们可以看到我正在尝试做的事情;) 我知道所有的锁定问题,等等。我正在试图找出信号和插槽如何与线程一起使用。
在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();
}
假设信号和插槽已在头文件中正确设置(我已经测试过它们)。现在,问题在于:
在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
}
问题是:因为MyReceiver对象是在main()中创建的,它位于主线程上,这是否意味着插槽(例如,gotit())将在主线程上运行,因此可以安全地执行GUI的东西?即使在信号来自不同的QThread的情况下(例如本例中的MyConsole)?
是否有更好的方法允许工作线程与GUI交互(例如,Obj-C / Cocoa在主线程上有“发送消息”类型的方法)。这样做的“Qt方式”是什么?
提前致谢!
答案 0 :(得分:5)
默认情况下(Qt :: AutoConnection),插槽将在创建QObject的线程中运行。因此,无论从哪个线程发出信号,插槽都将始终在线程中运行,QObject“生活“in(如果Qt事件循环在该线程中运行,否则无法传递事件)。由于主线程将成为Qt GUI线程,这将按预期工作。这确实是与GUI交互的Qt方式。 另请参阅:http://doc.qt.nokia.com/4.7/thread-basics.html(查找线程关联)。
答案 1 :(得分:2)
从一个线程发出信号并在另一个线程中接收信号的“Qt方式”是使用排队连接
connect( obj, SIGNAL(foo()), other_obj, SLOT(bar()), Qt::QueuedConnection )
来自Qt :: QueuedConnection的Qt文档:
当控制返回到接收者线程的事件循环时,将调用该槽。插槽在接收器的线程中执行。