2017-07-12 80 views
0

我想創建一個用於控制和監視QT工業機器的GUI。 GUI應該每300ms更新一次機器的測量結果。而且我應該能夠同時控制機器。我在做什麼(錯誤)是我正在嘗試使用每隔300ms觸發一次的定時器更新GUI中的測量值。但是,如果在定時器插槽執行的同時單擊我的控制按鈕,GUI不響應。我也嘗試過使用信號和插槽技術。同樣的結果。我無法在互聯網上找到解決方案。如果有人能幫忙,我會很高興。提前致謝。圖形用戶界面更新和控制同時在qt

+1

你能分享你的代碼嗎?您是否在代碼中使用了Sleep命令? – aghilpro

+0

你能分享你的代碼嗎?在大多數情況下,計時器是正確的選擇。如果點擊未執行,那麼可能是代碼中的一些問題,也許是一些阻塞功能,您可能會重新排列信號/插槽或線程。 – Damien

+0

感謝您的回覆。那麼你是否說,即使我在觸發計時器時點擊按鈕,它也不會造成任何問題?我會盡量明天發佈代碼..再次感謝 – user5160714

回答

0

我發現問題是什麼。這不是我認爲的。我正在請求我每隔30ms與之通信的機器狀態。我增加到3000毫秒,現在它工作正常。即使在另一個插槽正在執行時單擊,該按鈕也不會造成任何問題。問這是一個愚蠢的事情。感謝大家的幫助。所有的答案都非常豐富。再次感謝。

1

這樣做有三種主要方法,每種方法都有其優點和缺點。

簡單,非可擴展解決方案


最簡單的方法是手動調用QApplication::processEvents()你的「忙」的代碼中。例如,要手動更新GUI每個循環,你可以這樣做:

for (int i = 0; i < 5000; ++i) { 
    label->setText(tr("At Index %1...").arg(i)); 
    QApplication::processEvents(); 
} 

優點

  1. 很容易
  2. 沒有併發問題

缺點

  1. 非常有限的功能
  2. 污染代碼

線程

如果你想要一個簡單的解決方案,但可擴展的一個,繼承的QThread然後在運行非GUI任務單獨的線程是一個很好的方法:

class MyThread: QThread 
{ 
    Q_OBJECT 

    void run() 
    { 
     for (size_t i = 0; i < 50000; ++i) { 
      std::cout << i << std::endl; 
     } 
    } 
}; 

auto *thread = new MyThread; 
thread->start(); 

當這個長時間的任務發生時,GUI將會更新,而Qt將負責垃圾收集。


優點

  1. 相當簡單
  2. 魯棒的,可擴展和信號/槽允許數據交換

缺點

  1. 不能更新從主線程以外的任何線程的GUI。
  2. 信號/插槽必須使用QueuedConnection。

事件循環

最後一種方法是Qt的原生解決方案:一個QEventLoop。

QTimer timer; 
QEventLoop loop; 

timer.setSingleShot(true); 
connect(&timer, SIGNAL(timeout()), &loop, SLOT(quit())); 

timer.start(5000); 
loop.exec(); 

這實際上不那麼直觀,但是在大多數情況下通過避免繁忙的等待而好得多。


優點

  1. 最小CPU使用率

缺點

  1. 不太直觀。

您可以閱讀更多here。我最初擁有一個擁有相同信息的現代資源,所以如果你在Qt5文檔中找到類似的鏈接,請編輯這篇文章。

相關問題