2017-06-14 161 views
1

我試圖將信號從一個QObject連接到作爲QT5文檔中所定義的函子:連接(的QObject *,信號(信號()),算符)不QT5連接

http://doc.qt.io/qt-5/qobject.html#connect-5

相關代碼:

namespace someNamespace 
{ 
void processFinished() 
{ 
    qDebug() << "A Thread has finished processing!!!"; 
} 

void executeWorkerOnSeparateTread() 
{ 
    QThread* thread = new QThread; 
    Worker* worker = new Worker(); 
    worker->moveToThread(thread); 
    QObject::connect(worker, SIGNAL(finished()), thread, SLOT(quit())); 
    QObject::connect(worker, SIGNAL(finished()), worker, SLOT(deleteLater())); 
    QObject::connect(thread, SIGNAL(finished()), thread, SLOT(deleteLater())); 
    QObject::connect(thread, SIGNAL(started()), worker, SLOT(process())); 
    QObject::connect(worker, SIGNAL(finished()), processFinished); //DOES NOT COMPILE 
    thread->start(); 
} 
} 

如果我只是註釋掉沒有編譯的行,這段代碼編譯並執行時沒有問題。我只是無法獲得連接編譯。

編譯器錯誤:

當然
no matching function for call to 'QObject::connect(Worker*&, const char*, void(&)())' 

工作者繼承自QObject,並且在它的Q_OBJECT關鍵字。事實上,這種方法沒有問題的線路也消除了其他線路成爲問題。

任何想法,我在做什麼錯?在我看來,它應該是這個直截了當的。

如果相關,QT版本是5.8,GCC版本是4.8.5。

謝謝!

+5

不是你的問題的答案,只是一個評論:你爲什麼不使用新的編譯時檢查'連接'語法?你正在使用一個足夠新的Qt,它是可用的。擺脫醜陋的'SIGNAL'和'SLOT'宏,會給你編譯時錯誤,而不是無法建立連接時的運行時錯誤。 –

+1

@JesperJuhl其實我認爲這就是答案。查看文檔,使用函子的'connect()'靜態函數沒有支持舊信號/插槽語法的版本。 – MrEricSir

+0

@MrEricSir我會提交它作爲答案,然後我們會看到它是如何判斷;) –

回答

2

這是正確的,沒有辦法使用基於moc的信號和插槽連接到名稱空間或lambda中的函數。看看the list of overloads for QObject::connect()`,看看錯誤報道的原因。在這裏使用正確的函數是connect overload for a functor,它使用一個指向成員函數的第一個參數:

QMetaObject::Connection 
QObject::connect(const QObject *sender, PointerToMemberFunction signal, Functor functor) 

因此,使用:

QObject::connect(worker, &Worker::finished, processFinished); 

注意函數名後缺少一輪括號 - 不小心在那個日子裏讓我頭痛。

這也意味着您可能想要爲了統一起見而切換到新的語法。

有關更多詳細信息,請參閱Olivier Goffart撰寫的博客文章系列的part 1part 2以瞭解更多詳細信息。另請參見here兩種方法的詳細並行概要。

2

使用新的編譯時檢查連接語法。你正在使用一個足夠新的Qt,它是可用的。將擺脫醜陋的SIGNALSLOT宏,並會給你編譯時錯誤,而不是運行時錯誤,當無法建立連接時,這將與lambda和成員函數以及大多數其他可調用項一起使用。

+0

這個答案也是正確的,基本上與我接受的答案相同。無論如何,我將從現在開始轉向新的語法,因爲它似乎要優於舊的語法。謝謝! –