2011-08-18 1014 views
2

我想從QtConcurrent :: runQtConcurrent ::運行發射信號

這個函數中發出一個Qt信號這可能嗎?好像我的插槽永遠不會被調用。所有的信號,插槽和函數都是同一個類對象的一部分。我試圖在主線程和從線程中建立連接。我真的不在乎信號和插槽是否在同一個線程中,我只是想讓它發生。

由於

回答

1

可以使用Qt::QueuedConnection用於該連接(將它傳遞給connect呼叫該建立連接),由於信號將總是從比所述接收器對象的線程不同的線程發出的。

Qt::AutoConnection也會做同樣的事情,並且信號添加到接收對象的線程的事件隊列。

如果接收線程被阻塞,因而從未重新進入事件隊列,信號不能被接收對象的時隙中接收。

+0

這是不正確的:默認的自動連接將做的工作就好了。 –

+0

@KubaOber:你錯了。 OP表示所有插槽和信號都屬於一個對象。因此,AutoConnection將評估爲DirectConnection。這可能不是OP想要的,因爲這要求槽以線程安全的方式使用對象。這種同步必須在這種情況下手動完成。 QueuedConnection將消除手動同步的需要,因爲該槽將在對象所在的線程中調用。 Qt將處理實現該操作所需的同步。 – smerlin

+0

發件人的對象無關緊要。發送和接收線程之間的比較是在信號被髮射的時間完成的,並且在當前* *線程('的QThread :: currentThread')和* *目標線程('接收機 - >螺紋()')之間進行。 *發送對象的*線程在該確定中沒有任何形式。 –

2

以下使用Qt 4.8.7工作得很好。信號從工作線程發出,並在主線程中消耗。我們斷言該槽在主線程中運行,並且該仿函數在工作線程中運行。

// https://github.com/KubaO/stackoverflown/tree/master/questions/concurrent-emit-qt4-7114421 
#include <QtCore> 

class Helper : public QObject { 
    Q_OBJECT 
public: 
    int n = 0; 
    Q_SLOT void increment() { 
     Q_ASSERT(QThread::currentThread() == qApp->thread()); 
     n++; 
    } 
}; 

int main(int argc, char **argv) 
{ 
    QCoreApplication app(argc, argv); 
    Helper helper; 
    Q_ASSERT(helper.n == 0); 
    QtConcurrent::run([&]{ 
     Q_ASSERT(QThread::currentThread() != qApp->thread()); 
     QObject src; 
     QObject::connect(&src, SIGNAL(destroyed(QObject*)), &helper, SLOT(increment())); 
     QObject::connect(&src, SIGNAL(destroyed(QObject*)), &app, SLOT(quit())); 
    }); 
    app.exec(); 
    Q_ASSERT(helper.n == 1); 
} 

#include "main.moc" 

在Qt 5,你不需要輔助類來證明它的工作原理:

#include <QtConcurrent> 

int main(int argc, char **argv) 
{ 
    QCoreApplication app(argc, argv); 
    int n = 0; 
    Q_ASSERT(n == 0); 
    QtConcurrent::run([&]{ 
     Q_ASSERT(QThread::currentThread() != qApp->thread()); 
     QObject src; 
     QObject::connect(&src, &QObject::destroyed, &app, [&]{ 
     Q_ASSERT(QThread::currentThread() == qApp->thread()); 
     n ++; 
     qApp->quit(); 
     }); 
    }); 
    app.exec(); 
    Q_ASSERT(n == 1); 
}