按下串列框行后,將啟動一個執行緒,該執行緒:
- 清除樹視圖(它的串列存盤)
- 然后,將專案添加到樹視圖(或者更確切地說是它的串列存盤)。
該行可以被多次按下,這意味著它可以產生多個執行緒,這些執行緒可能最終同時運行。
問題是,如果多次快速按下該行,則樹視圖最終會出現重復條目??。這是由并行運行的多個執行緒引起的,所有執行緒都試圖在樹視圖中添加同一組專案。
這個問題的解決方案是在任何時候都只允許執行緒的一個實體運行。這可以通過以下任一方式完成:
如果執行緒當前正在運行,則阻止新執行緒實體啟動
停止已經運行的執行緒實體,然后再啟動一個新實體
問題是我不知道如何實施這兩種解決方案。
代碼:
class Main(Gtk.Window):
def __init__(self):
Gtk.Window.__init__(self)
self.connect("destroy", Gtk.main_quit)
self.liststore = Gtk.ListStore(str)
self.treeview = Gtk.TreeView()
self.treeview.set_model(self.liststore)
cellrenderertext = Gtk.CellRendererText()
treeviewcolumn = Gtk.TreeViewColumn("Items", cellrenderertext, text=0)
self.treeview.append_column(treeviewcolumn)
self.button = Gtk.Button(label='Button')
box = Gtk.Box()
box.set_orientation(Gtk.Orientation.VERTICAL)
box.add(self.button)
box.add(self.treeview)
self.add(box)
self.button.connect('clicked', self.button_clicked)
def button_clicked(self, widget):
def threaded():
self.liststore.clear()
self.liststore.append(['first_item'])
time.sleep(0.1)
self.liststore.append(['second_item'])
time.sleep(0.1)
self.liststore.append(['third_item'])
threading.Thread(target=threaded, daemon=True).start()
if __name__ == '__main__':
window = Main()
window.show_all()
Gtk.main()
我添加了time.sleep(0.1)
以模擬添加的每個專案之間的延遲。多次按下按鈕將導致樹視圖中出現重復的條目。預期的輸出是:
first_item
second_item
third_item
但是,真正快速按下按鈕會導致:
first_item
third_item
second_item
third_item
uj5u.com熱心網友回復:
您應該使用變數來保持執行緒并檢查此變數。
在__init__
集合變數中
self.thread = None
當你按下按鈕然后檢查這個變數
#if (self.thread in None) or (self.thread.is_alive() is False):
if not self.thread or not self.thread.is_alive():
self.thread = threading.Thread(...)
self.thread.start()
而不是檢查is_alive()
你可以設定self.thread = None
在執行緒的末尾。
uj5u.com熱心網友回復:
請注意,所有告訴您如何在 Python 中處理執行緒的評論或答案對于關于多執行緒的狹隘問題可能是部分正確的,但它們并不是您真正想要的。
您應該意識到,除非明確提及,否則幾乎所有 GTK/GLib API(如Gtk.ListStore
)都不是執行緒安全的。如果您要從與主執行緒不同的執行緒呼叫這些函式,您應該準備好遇到隨機且難以除錯的問題。
在這種情況下,如果你想從不同的執行緒更新你的 Gtk.ListStore,你需要確保你使用了一個函式,比如GLib.idle_add()
在主執行緒中更新存盤。
您可能還想閱讀有關執行緒和并發的 PyGObject 教程
轉載請註明出處,本文鏈接:https://www.uj5u.com/caozuo/507350.html
上一篇:如何按屬性對嵌套物件進行排序?