“这与上述的预期使用目的相矛盾。我错过了什么吗?”
是的,我认为你误解了线程亲和性(对象所在的线程)的概念。
让我们用最简代码举个例子:-
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 exec的签名是:-
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)
{
...
...
bool bStop = false;
while(!bStop)
{
}
}
QThread
以外的对象移至线程中。这样,在新的线程中不会执行除run
之外的任何QThread
方法。 - Kuba hasn't forgotten Monica