我正在使用PyGTK來構建GUI應用程序。我想從另一個線程更新文本視圖窗口小部件,但每次嘗試更新時,窗口小部件都不會更新。我應該做些什麼才能獲得可靠的GUI更新?使用PyGtk時GUI不會從另一個線程更新
6
A
回答
12
GTK +不是線程安全的,所以您不應該簡單地從其他線程調用GUI更新方法。 glib.idle_add(或舊版PyGTK版本中的gobject.idle_add)可用於此目的。
而是寫的:
label.set_text("foo")
你可以這樣寫:
glib.idle_add(label.set_text, "foo")
這將導致函數調用的GTK +排隊。
如果您需要運行多個語句,它往往更容易將它們包裝在一個函數:
def idle():
label1.set_text("foo")
label2.set_text("bar")
glib.idle_add(idle)
確保函數傳遞給idle_add
不返回True
;否則它會再次排隊。
編輯:正如Daniel指出的那樣,您需要首先在您的程序的任何地方撥打gtk.gdk.threads_init()
。
-1
可以使用gobject.idle_add方法,其語法和上面一樣,你必須導入模塊GObject的
2
正如在以前的答案陳述來實現,GTK是不一樣的「線程安全的」,但它是「線程感知」 - 請參閱主題:https://developer.gnome.org/gdk2/stable/gdk2-Threads.html
爲了從另一個線程修改GTK小部件,您必須使用GTK的鎖定。呼叫gtk.threads_init()
導入GTK模塊後,然後您可以更新,像這樣:
gtk.threads_enter()
# make changes...
gtk.threads_leave()
注意上面將無法工作在Windows上(見上面的鏈接)。在Windows上,您必須使用gobject.idle_add()
,如上所述,但不要忘記在代碼中導入gobject後直接輸入gobject.threads_init()
! idle_add()函數將在主線程(運行gtk.main()的線程)中執行更新本身。
-1
約翰內斯說的是正確的,但是因爲GTK是glib和gobject事物的包裝器,所以實際上你會想要使用gtk.idle_add()。不需要不必要的進口。
相關問題
- 1. 從另一個線程更新GUI線程
- 2. PySide:從另一個線程更新GUI更容易的方法
- 3. 如何從另一個線程更新GUI?
- 4. 從Visual C++ 2008中的另一個線程更新GUI
- 5. 從另一個類的後臺線程更新GUI控件
- 6. 當從另一個線程更新時,DataGridView不會重新繪製自己
- 7. PyGTK與線程,gobject,從另一個線程發送信號?
- 8. PyGTK阻止非GUI線程
- 9. 從線程更新Swing GUI
- 10. 從C#中的另一個線程更新GUI - 切換回主線程?
- 11. C#Windows窗體應用程序 - 從另一個線程和類更新GUI?
- 12. PyQt - 從另一個線程修改GUI
- 13. 更新的JLabel從另一個線程
- 14. 從另一個線程更新UI(progressDialog)
- 15. 從另一個線程javafx更新ImageView
- 16. ProgressBar從另一個線程更新
- 17. 從另一個線程更新UI
- 18. 更新從另一個線程treeview
- 19. 從另一個類更新GUI?
- 20. 更新在C#GUI一個進度條,從另一個線程和類
- 21. 創建一個GUI更新線程
- 22. 使用invokeLater或SwingWorker從另一個線程更新Swing組件
- 23. 線程不會更新textview兩次啓動另一個活動
- 24. 從QT中的另一個GUI線程調用線程時出現問題
- 25. 使用另一個線程或反之亦然更新主GUI顯示
- 26. 即使更新從主線程調用,UI也不會更新
- 27. 從另一個實例調用方法時,listview不會更新
- 28. setText()不會反映從另一個線程調用時發生的更改
- 29. 從另一個線程更新主線程中的ListView
- 30. 支持從另一個線程創建GUI的GUI庫
好點。有關這兩種方法的另一個好消息可以在PyGTK FAQ條目中看到:http://faq.pygtk.org/index.py?file=faq20.006.htp&req=show – 2010-01-15 08:13:09