#python #gtk #pygtk #gtktreeview
#python #gtk #pygtk #gtktreeview
Вопрос:
У меня есть кнопка, и я хочу, чтобы выбранная строка мигала. Кто-то должен нажать кнопку мигания, а затем нажать событие, to_blink
запустив поток _blink
, который изменяет значения элементов 3-6 str в MyTreeStore
.
import threading
import time
class MyTreeStore(Gtk.TreeStore):
def __init__(self):
# i use the 3 last str's for the background colors
Gtk.TreeStore.__init__(self, str, str, str, str, str, str)
class TestBox(Gtk.VBox):
def __init__(self):
self.treestore = MyTreeStore()
self.treeview = Gtk.TreeView()
self.treeview.set_model(self.treestore)
renderer_col1 = Gtk.CellRendererText()
column_1 = Gtk.TreeViewColumn("Col1", renderer_col1, text=0, cell_background=3)
...
self.blink_button = Gtk.Button('Blink')
self.is_connected_button.connect('clicked', self.to_blink)
def to_blink(self, button):
""" take certain row, start thread which change background-color """
tree_selection = self.treeview.get_selection()
tree_model, treepath = tree_selection.get_selected()
if treepath:
tree_model[treepath][3] = "green"
tree_model[treepath][4] = "green"
tree_model[treepath][5] = "green"
t = threading.Thread(target=self._blink, args=(tree_model[treepath],))
t.daemon = True
t.start()
def _blink(self, path):
for i in range(100):
path[3] = "green"
path[4] = "green"
path[5] = "green"
time.sleep(1)
path[3] = "white"
path[4] = "white"
path[5] = "white"
Ответ №1:
При работе с GTK следует максимально избегать многопоточности. В этом случае это можно было бы решить с помощью GLib.timeout_add
вместо этого.
Заменить:
t = threading.Thread(target=self._blink, args=(tree_model[treepath],))
t.daemon = True
t.start()
С помощью:
GLib.timeout_add(1000, self._blink_glib, tree_model[treepath])
def _blink_glib(self, path):
for i in range(3, 6):
if path[i] == "white":
path[i] = "green"
else:
path[i] = "white"
return True
Обратный вызов должен вернуться, True
чтобы продолжить работу или False
остановиться. Таким образом, вам все еще нужно реализовать флаг, чтобы указать, выполнены ли 100 итераций.
Еще одно замечание: если все столбцы будут мигать одним цветом, нет необходимости создавать три дополнительных элемента treestore, достаточно одного и указать все три столбца cell_background
на этот элемент.
column_1 = Gtk.TreeViewColumn("Col1", renderer_col1, text=0, cell_background=3)
column_2 = Gtk.TreeViewColumn("Col2", renderer_col2, text=0, cell_background=3)
column_3 = Gtk.TreeViewColumn("Col3", renderer_col3, text=0, cell_background=3)
def _blink_glib(self, path):
path[3] = "green" if path[3] == "white" else "white"
return True