2011-10-24 30 views
1

我有一個使用Qt Creator和隨附的GUI工具開發的Qt應用程序。我有一個主線程TheGui和由主線程WorkerThread(稱爲thread)創建的工作線程。Qt QThread使用從工作人員到gui的信號/插槽出現問題

時遇到的問題是,當我通過使用

public slot: 
    void updateTable(string str); 

工作線程的標題文件內的GUI和信號void sendList(string str);的頭文件內創建從未在GUI的槽,所述槽被調用。我連接兩個使用

connect(&thread, SIGNAL(sendList(string str), 
     this, SLOT(updateTable(string str))); 

內的GUI cpp文件中的構造函數。除了工作線程中的插槽和來自GUI的信號之外,我做了類似的事情,它工作正常。我知道從使用調試器,信號sendList確實被調用,它只是永遠不會進入它。

有什麼想法?

+0

請參閱http://stackoverflow.com/questions/4927860/how-to-pass-variables-to-slot-methods-in-qt –

回答

4
  1. 由於信號和槽都在不同的線程,它們之間的連接具有Qt::QueuedConnection類型。而對於排隊連接,Qt必須能夠保存信號參數的副本,以便稍後將其傳遞給插槽。
    因此,通知的Qt該類型是可複製,你必須使用Qt的元對象系統(見QMetaType)這樣註冊它:

    // This macro call should be put in one of your .h files 
    Q_DECLARE_METATYPE(std::string) 
    
    // You should call this function before any (queued) 
    // signal/slot connection involving the type 
    qRegisterMetaType<std::string>(); 
    
  2. 參數名稱不應該包含在QObject::connect打電話,類型名稱應該是爲那些你傳遞給Q_DECLARE_METATYPE如出一轍:

    connect(&thread, SIGNAL(sendList(std::string), this, SLOT(updateTable(std::string))); 
    

您還可以使用QStringQByteArray,它們已經被註冊,而不是std::string,因爲這些函數是插槽和信號,因此已經是Qt特定的。

+0

感謝您的迴應!我實際上通過使用指針來解決這個問題。我在哪裏可以調用qRegisterMetaType?我不斷收到錯誤'從'int qMetaTypeId(T *)[與T = StringVector]'實例化'其中StringVector是我想要聲明的。 –

+0

@Kyle也許你沒有在你使用qRegisterMetaType的.cpp文件中使用Q_DECLARE_METATYPE的頭文件。 – alexisdm

+0

在標題中是否需要放置它?在Q_OBJECT下?另外,我已經切換到使用QVector 並通過使用插槽。根據我一直在看的文檔,這不是自動註冊? –

1

確定連接實際上是由?如果連接呼叫有任何問題,通常在cerr上有關於它的一些調試輸出。

其次,我認爲你有一個錯字 - 如果你複製了你的代碼連接調用,然後知道你有括號周圍信號欠缺 - 應該是

connect(&thread, SIGNAL(sendList(string)), this, SLOT(updateTable(string))); 

第三,什麼是要傳遞的信號/插槽參數?它是std :: string嗎?線程之間的連接必須是排隊連接。排隊連接可以使用僅用作Q_DECLARE_METATYPE宏聲明的類型的參數,並且使用qRegisterMetaType註冊。據我所知,Qt在默認情況下不會聲明std::string,因爲它更喜歡QString。如果您沒有將這些添加到代碼中,可能是失敗的原因。