我正在浏览链接
我对一些陈述感到困惑。在第一个链接中,它表示
QThread中的所有函数都是编写的,并且打算从创建线程调用,而不是QThread启动的线程。
虽然它建议使用moveToThread
将对象移动到新线程,而不是子类化QThread
。我的问题是:
run
方法的默认实现调用exec
,创建事件循环,以及对象的线程关联使用moveToThread
进行更改,所有slots
都将在新主题中执行,而不是在创建主题中执行,这与上述内容相矛盾预期用途。我错过了什么吗?
第二个问题:
在第三个链接中说
事件队列属于线程而不是事件循环,并且由该线程中运行的所有事件循环共享。
我的问题是如何在单个线程中有多个事件循环?我理解的是,事件循环循环遍历事件队列,直到调用exit
/ terminate
,并处理每个{{1到达那个队列。如果这是真的,一个循环将永远不会结束(除非调用event
/ exit
),另一个循环将如何开始?任何展示它的示例代码都将受到高度赞赏。
答案 0 :(得分:4)
"这与上述预期用途相矛盾。我错过了什么吗?"
是的,我认为您误解了线程关联的概念(运行对象的线程)。
让我们用最少的代码举例: -
QThread* pThread = new QThread; // QThread on the main thread
MyObject* myObj = new MyObject; // MyObject on the main thread
myObj->moveToThread(pThread); // MyObject on the new thread, controlled by pThread
pThread->start(); // pThread instance is still on the main thread
假设此代码是从一个对象创建的,该对象的线程亲和性是主线程,例如QMainWindow
,则线程对象pThread
正在主线程上运行;它的线程亲和力是主线程。
相反,QObject
派生的MyObject
实例myObj
已移至新主题pThread
。因此,myObj
的线程亲和性现在是新线程。
为QThread
"编写的" 函数仍然直接从主线程调用,就像它正在运行的那样。
将QThread
视为线程控制器对象,而不是线程本身。这是为什么经常不鼓励继承QThread
的原因之一,除非您想要更改QThread
管理底层线程的方式。
如何在一个线程中有多个事件循环?...
我自己并没有直接使用过这个,但我会按照我的理解来解释这一点。也许其他人将能够纠正或确认这一点。从Qt Documentation for QEventLoop开始,它指出: -
您可以随时创建
QEventLoop
对象并在其上调用exec()
以启动本地事件循环。
QEventLoop执行官的签名是: -
int QEventLoop :: exec(ProcessEventsFlags flags = AllEvents)
因此,如果传入一组标志,则只处理这些事件。现在,当调用exec()
开始处理事件直到调用exit()
时,您可以创建一个本地事件循环,让您的程序等到一个或多个特定事件发生。
第二个事件循环是主事件循环中的本地事件循环,但是由于每个事件循环都可以处理整个事件队列(由线程中的所有事件循环共享),因此它可以用于覆盖事件处理主事件循环。
如果您将事件循环概念化为执行此类操作(伪代码): -
QList<QEvent*> eventList;
while(!stop)
{
// handle events in eventList
}
第二个事件循环将执行此操作: -
bool bStop = false;
QList<QEvent*> eventList;
while(!bStop)
{
// handle events in eventList
...
...
// Inner event loop
bool bStop = false;
while(!bStop)
{
// handle events in eventList
}
}