2014-02-21 45 views
0

我有一個Qt項目,它有多個UI。我想每隔20秒檢查一次wifi信號強度,並用信號強度值更新我所使用的任何UI形式。我用基類QThread創建了一個myThread類,並重新實現了run.Here我有一個超時時間爲20秒的計時器。該線程在main.cpp類中啓動。QThread發出的信號連接到多個UI類

void Thread_UpdateWifiSignal::run() 
{ 
    QTimer timer; 
    connect(&timer, SIGNAL(timeout()), this, SLOT(timerHit()), Qt::DirectConnection); 
    timer.setInterval(20000); 
    timer.start(); // puts one event in the threads event queue 
    exec(); 
    qDebug() << "stopping timer"; 
    timer.stop(); 
} 

在我已經寫了代碼來獲取WiFi信號強度,然後一個信號被髮射用的WiFi信號強度的更新值的timehit槽。

void Thread_UpdateWifiSignal::timerHit() 
{ 
    QMutex mutex; 
    mutex.lock(); 

    int SignalQuality = CheckWifiNetwork(); 

    emit this->UpdatedSignalQuality(SignalQuality); 

    mutex.unlock(); 

} 

int Thread_UpdateWifiSignal::CheckWifiNetwork() 
{ 
    //Code to get wifi signal strength 
} 

我在所有的UI中都有一個快捷面板,它有一個顯示wifi圖標的標籤。我想將線程發出的信號連接到UI類中的插槽,以更新與wifi信號強度相關的圖標wifi棒。

我看到線程正在運行,但我實例化了UI窗體類中的myThread類,要連接發送到插槽的信號,我注意到發出的信號沒有連接到插槽。

我該怎麼辦?

+2

對'QThread'進行子類化並使用插槽會帶來麻煩。 [「重要的是要記住QThread對象通常位於創建它的線程中,而不是它所管理的線程中。這個經常被忽視的細節意味着QThread的插槽將在其主線程的上下文中執行,而不是在其正在管理的線程的上下文中執行。出於這個原因,在QThread子類中實現新的插槽是容易出錯和不鼓勵的。](https://qt-project.org/doc/qt-5.0/qtcore/qthread.html#details) – thuga

回答

0

此刻,信號被髮布到您的線程的事件循環中,導致您的子類線程中執行處理程序插槽,而不是您的「主線程」(管理GUI組件),因此不會出現GUI更改。

您必須將信號UpdatedSignalQuality從子類線程連接到處理程序插槽,並使用第三個參數作爲Qt :: QueuedConnection而不是Qt :: DirectConnection,然後將信號發佈到主線程的事件循環中。

更多詳細信息differences between QueuedConnection and DirectConection