- QObject::QObject(QObject *parent)
- : d_ptr(new QObjectPrivate)
- {
- Q_D(QObject);
- d->threadData = (parent && !parent->thread()) ? parent->d_func()->threadData : QThreadData::current();
- if (parent) {
- if (!check_parent_thread(parent, parent ? parent->d_func()->threadData : 0, d->threadData))
- parent = 0;
- setParent(parent);
- }
如上代码可以得出如下结论:
- void QObject::moveToThread(QThread *targetThread)
- {
- Q_D(QObject);
- if (d->parent != 0) {
- qWarning("QObject::moveToThread: Cannot move objects with a parent");
- return;
- }
- if (d->isWidget) {
- qWarning("QObject::moveToThread: Widgets cannot be moved to a new thread");
- return;
- }
-
- QThreadData *currentData = QThreadData::current();
- QThreadData *targetData = targetThread ? QThreadData::get2(targetThread) : new QThreadData(0);
- if (d->threadData->thread == 0 && currentData == targetData) {
- // one exception to the rule: we allow moving objects with no thread affinity to the current thread
- currentData = d->threadData;
- } else if (d->threadData != currentData) {
- qWarning("QObject::moveToThread: Current thread (%p) is not the object's thread (%p)./n"
- "Cannot move to target thread (%p)/n",
- currentData->thread, d->threadData->thread, targetData->thread);
- return;
- }
- ......
通过如上代码可以看到movetothread的限制条件如下:
个人理解:每个线程都有自己的事件循环,并不是一个程序只有一个事件循环,调用movetothread后,即将该对象相关的事件推送的到对应新线程的事件循环,新线程会将事件推送到对应对象的event方法进行分发处理。所以只有事件类型的才可以在新线程中执行(即只能通过信号槽机制来调用,因为跨线程信号槽机制会触发事件推送;在另外一个线程中通过函数调用的方式调用该对象的方法不会在新线程中执行,而是在调用线程执行)。
movetothread是一种多线程的实现方式
对于事件驱动机制来说,例如“定时器”或者“网络”模块,他们只能在单一进程中使用,例如不能一个线程创建一个定时器,而在另外一个线程开始或者结束该定时器。这些操作都不可取。