2013-03-14 87 views
1

假設我有多線程應用程序。然後根據Qt哲學,您甚至不能修改在GUI中添加的Widgets的屬性。假設類別Not_GUI的對象已被移動到另一個QThread,那麼在Not_GUI的函數中調用button1->SetEnabled(false);button1是添加在GUI中的QPushButton)是非法的。在Qt中修改非GUI線程中的小部件?

目前我的應用程序有許多GUI widgets(如QLabel,QLineEdit的,等等)&,因爲所有的events只有1線程的應用程序掛起了一陣處理,由於巨大的繪畫活動。 有沒有辦法讓我可以以某種方式將Widgets的一些工作量分配給各種線程?

回答

1

第一個例子使用信號和插槽。 QWidget::setEnabled()是一個插槽。創建一個信號modifyWidgetEnableState(bool)並連接到插槽。觸發信號而不是使用直接方法調用。

應用程序掛起了一會兒,由於巨大的繪畫活動

難道這些小部件的Qt構建?如果是的話,我懷疑這是因爲這幅畫的緣故。這些小工具是你的嗎?那麼你可能在你的子類事件處理器中做了太多的處理。要做的第一件事就是嘗試提高你所做的任何事情的性能,第二件事是在線程中移動繁重的處理,並且(再次)使用信號和插槽與小部件進行通信。

編輯: 假設o1和o2並被移動到不同的線程t1和t2。

每當o2->slot()被作爲正常的函數調用執行則它是調用線程正在執行slot()。記住,slot()畢竟是一個正常的C++方法。每當連接到slot()的信號被觸發,則它是接收線程正在執行slot()。所以選擇一個或另一個,否則你將受到競爭條件。

+0

關於SIGNAL&SLOT ans: SLOT上的處理是否完成GUI線程或SIGNAL發出的線程? 是的小部件只是Qt構建我還沒有創建任何自定義小部件。使用像QLabel,QLineEdit這樣的小部件。掛起是由於繪畫只是因爲如果我不添加該QGridLayout到GUI然後沒有掛起。通過掛斷我的意思是,應用程序不響應點擊和顯示(沒有響應)和Windows 7中的圓形光標。 我沒有處理任何事件我自己。一切都由Qt的功能來處理。 – 2013-03-14 10:21:44

+1

如果'o1'和'o2'被***移動到***不同線程't1'和't2','o1'觸發信號,那麼'o2'的槽將由線程't2執行'。如果你直接調用'o2-> slot()',那麼它將像任何正常的函數調用一樣被執行。但是這是多線程的問題。 – UmNyobe 2013-03-15 09:09:29

+0

這個坑不是由於繪畫。無限期地不。這是由於你的函數在主線程中做了大量的處理,這會妨礙顯示畫圖代碼的執行。 – UmNyobe 2013-03-15 09:11:39

0

正如你所說,Qt要求在主線程中完成所有的widget繪製。這是沒有辦法的。您可以在一個單獨的線程中將可以塗成QImage,然後只需將圖像繪製到其小部件paintEvent()中。但是,首先要記住,這會佔用所有緩衝圖像的額外內存。另外,如果你能夠做到這一點,那麼採用相同的方法而不用線程就可能更容易。一般而言,您的目標應該是在paintEvent()內儘可能少地完成工作。

0

你可以調用任何函數來通過QMetaObject::invokeMethod()從另一個線程修改你的UI,並在可以使用QtConcurrent::run(我與QFutureWatcher一起使用它)的單獨線程中運行某個函數。可能不是規範的Qt方式,但對我來說很好,如果我不想爲每個函數創建我自己的QThread ::運行