2017-06-05 56 views
1

我仍然在努力讓這個工作正如我所期望的那樣。Qt-使用不同線程的信號和插槽

我有一個Qt項目,我想根據不同線程的信號狀態進行更新。我的主GUI線程應該啓動一個工作線程,按下開始按鈕運行。

工作者線程應該執行一個函數,它連續輪詢屬於另一個類的變量,這些變量即使是不同的線程(我正在使用portaudio庫)也被更新。然後它應該觸發一個信號(sendNewSig),它連接到我的GUI類中的一個槽(DrawData)。

問題是當我按下我的開始按鈕時,程序崩潰。我相信我錯過了一些重要的步驟來開始執行工作線程。通過在單擊開始按鈕時調用updater-> PollSignal(),我期待它在新線程中運行,但可能不會。我已經展示了下面的部分代碼,希望足以讓我的想法貫穿始終。

提前許多感謝所有幫助

在GUIApp.cpp

AudioGuiApplication::AudioGuiApplication(QWidget *parent) 
: QMainWindow(parent) 
{ 
    ui.setupUi(this); 

    //...... other stuff 

    thread = new QThread(this); 
    updater = new GUIUpdater(&audio_processor); 
    updater->moveToThread(thread); 

    connect(updater, SIGNAL(sendNewSig(string)), this, SLOT(DrawData(string))); 

    connect(thread, SIGNAL(destroyed()), updater, SLOT(deleteLater())); 

    actionText->setPlainText("Press Start to begin "); 
} 

void AudioGuiApplication::on_startButton_clicked() 
{ 
    updater->PollSignal(); 
} 

在GUIUpdater.cpp`

void GUIUpdater::PollSignal() 
{ 
    string str; 

    while (!ap->IsNewDataFound()) 
    { 
     emit sendNewSig(str); 
     ap->SetNewSigFound(false); 
    } 
}` 

回答

2

您從主/ GUI線程調用PollSignal功能直。

我覺得在所需的線程來執行它的最簡單的方法是使用一個單杆QTimer設定的信號&插槽機制在無延遲(0爲0毫秒):

void AudioGuiApplication::on_startButton_clicked() 
{ 
    QTimer::singleShot(0, updater, &GUIUpdater::PollSignal); 
} 

通過方式:你應該考慮移動到不依賴於宏的"new" connect syntax,而是允許編譯時類型驗證。

+1

謝謝。我試過了。然而,GUI並沒有像我預期的那樣被更新。由於我的信號連接到我的插槽是這樣的:connect(updater,SIGNAL(sendNewSig(string)),this,SLOT(DrawData(string)));當我在我的輪詢函數中發出sendNewSig(str)時,不應該用str作爲參數調用我的GUI類的DrawData函數嗎? DrawData不是一個插槽,只是一個普通的成員函數 – Engineer999

+0

'DrawData' *必須*是舊式'connect'語法的一個插槽。另外,你需要在Qt的反射機制中註冊'string':http://doc.qt.io/qt-5/qmetatype.html#qRegisterMetaType否則Auto/QueuedConnection(它在你的情況下)不會工作。我認爲這不是問題,因爲問題不是關於它:) – krzaq

+0

寄存器字符串在反射機制?我不確定我明白。我如何以及在哪裏可以做到這一點?謝謝 – Engineer999