GTK Python 更新树视图
GTK Python Update Treeview
我有一个由 Python 3.8 代码调用的 GTK3 GUI。在 GUI 上添加了树视图。我想每 1 秒更新一次树视图,但它使用了太多 CPU 电源并在大约 10 秒后崩溃。当我使用较小的数据时。当使用更大的数据(250 行)并立即给出错误:
Backend terminated or disconnected. Use 'Stop/Restart' to restart.
高效更新数据的解决方案是什么?
代码示例:
import gi
gi.require_version('Gtk', '3.0')
from gi.repository import Gtk
builder = Gtk.Builder()
builder.add_from_file('example.glade')
builder.get_objects()
window1 = builder.get_object('window1')
class Signals:
def on_window1_destroy(self, widget):
Gtk.main_quit()
def data_add(thread1):
while True:
starttime1 = time.time()
time.sleep(1 - ((time.time() - starttime1) % 1))
dict1 = {1: {"name": "data1", "content": "data2", "date": "data3"},
2: {"name": "data4", "content": "data5", "date": "data6"},
3: {"name": "data7", "content": "data8", "date": "data9"},
.
.
.
250: {"name": "datax", "content": "datay", "date": "dataz"}}
.
.
# Dictionary data converted to list data.
.
.
global initial_run
if initial_run == 1:
treeview1 = Gtk.TreeView()
liststore1 = Gtk.ListStore(str, str, str, int, float)
treeview1.set_model(liststore1)
for i in range(0, 250):
liststore1.append([list_data1[i], list_data2[i], list_data3[i], list_data4[i]])
if initial_run == 1:
for i, column in enumerate(process_columns):
cell = Gtk.CellRendererText()
col = Gtk.TreeViewColumn(column, cell, text=i)
treeview1.append_column(col)
treeview1.show()
initial_run=0
thrd = threading.Thread(target=data_add, args = ("thread1", ), daemon=True)
thrd.start()
builder.connect_signals(Signals())
window1.show_all()
Gtk.main()
您消耗这么多 CPU 的原因是因为您实施了一个 busy loop,它重复添加(而不是更新)250 行到您的 Gtk.TreeView
。另一个问题是您从不同的线程调用 Gtk API,这是不允许的,因为 GTK 明确地不是线程安全的。
要在主线程上定期执行一个函数(或者实际上是回调),您可以使用 API 例如 GLib.timeout_add_seconds()
. If you reallly have work that needs to be done on a different thread, you should perform your operations in the thread and call GLib.idle_add()
来用结果更新树视图。
就树视图本身的更新而言:对于数据集中的每一行,您首先必须在列表存储中找到一个现有条目并更新它,而不是尝试不断创建一个新条目。
我有一个由 Python 3.8 代码调用的 GTK3 GUI。在 GUI 上添加了树视图。我想每 1 秒更新一次树视图,但它使用了太多 CPU 电源并在大约 10 秒后崩溃。当我使用较小的数据时。当使用更大的数据(250 行)并立即给出错误:
Backend terminated or disconnected. Use 'Stop/Restart' to restart.
高效更新数据的解决方案是什么?
代码示例:
import gi
gi.require_version('Gtk', '3.0')
from gi.repository import Gtk
builder = Gtk.Builder()
builder.add_from_file('example.glade')
builder.get_objects()
window1 = builder.get_object('window1')
class Signals:
def on_window1_destroy(self, widget):
Gtk.main_quit()
def data_add(thread1):
while True:
starttime1 = time.time()
time.sleep(1 - ((time.time() - starttime1) % 1))
dict1 = {1: {"name": "data1", "content": "data2", "date": "data3"},
2: {"name": "data4", "content": "data5", "date": "data6"},
3: {"name": "data7", "content": "data8", "date": "data9"},
.
.
.
250: {"name": "datax", "content": "datay", "date": "dataz"}}
.
.
# Dictionary data converted to list data.
.
.
global initial_run
if initial_run == 1:
treeview1 = Gtk.TreeView()
liststore1 = Gtk.ListStore(str, str, str, int, float)
treeview1.set_model(liststore1)
for i in range(0, 250):
liststore1.append([list_data1[i], list_data2[i], list_data3[i], list_data4[i]])
if initial_run == 1:
for i, column in enumerate(process_columns):
cell = Gtk.CellRendererText()
col = Gtk.TreeViewColumn(column, cell, text=i)
treeview1.append_column(col)
treeview1.show()
initial_run=0
thrd = threading.Thread(target=data_add, args = ("thread1", ), daemon=True)
thrd.start()
builder.connect_signals(Signals())
window1.show_all()
Gtk.main()
您消耗这么多 CPU 的原因是因为您实施了一个 busy loop,它重复添加(而不是更新)250 行到您的 Gtk.TreeView
。另一个问题是您从不同的线程调用 Gtk API,这是不允许的,因为 GTK 明确地不是线程安全的。
要在主线程上定期执行一个函数(或者实际上是回调),您可以使用 API 例如 GLib.timeout_add_seconds()
. If you reallly have work that needs to be done on a different thread, you should perform your operations in the thread and call GLib.idle_add()
来用结果更新树视图。
就树视图本身的更新而言:对于数据集中的每一行,您首先必须在列表存储中找到一个现有条目并更新它,而不是尝试不断创建一个新条目。