在python中定期更新gtk的列表存储

2024-09-27 09:35:15 发布

您现在位置:Python中文网/ 问答频道 /正文

我是新来的phyton编程和开发图形用户界面有gtk框架和串口。它有一个treeview,它的liststore模型。我可以很容易地插入新行。 我在不同的线程中使用serialport recive回调,以避免丢失任何数据。在接收到新数据后,它应该更新treeview。但是,由于serialport在不同的线程中,我不知道如何更新列表。请帮我做这个。在

gui类:

class MainGUI():
def __init__(self):
    self.builder = Gtk.Builder()
    self.builder.add_from_file("main.glade")
    self.builder.connect_signals(MainGUI)
    self.window = self.builder.get_object("window1")
    self.mycombobox = self.builder.get_object('comboboxtext1')
    self.toggle = self.builder.get_object('togglebutton1')
    self.table = self.builder.get_object('treeview2')
    self.list = self.builder.get_object('liststore1')
    self.scroll_window = self.builder.get_object('scrolledwindow1')

def show(self):
    print("App main thread number", format(threading.get_ident()))
    self.window.show()
    Gtk.main()

@staticmethod
def connect_toggled(_self):
    if main.toggle.get_active():
        main.toggle.set_label("Disconnect")
        serial_port.connect(main.mycombobox.get_active_text())
        t3 = threading.Thread(target=serial_port.read_from_port)
        t3.start()
        serial_port.disconnect()

def row_inserted_event(self, path, iter):
    """The actual scrolling method"""
    adj = main.scroll_window.get_vadjustment()
    adj.set_value(adj.get_upper() - adj.get_page_size())

def update_table(self):
    # for i in range(256):
    #     main.list.append(['aaa', 'ddds', i])
    #     if len(main.list) > 50:
    #         main.list.remove(main.list.get_iter(0))
    main.list.append(['aaa', 'ddds', 0])
    if len(main.list) > 50:
        main.list.remove(main.list.get_iter(0))
    print(len(main.list))

if __name__ == "__main__":
    serial_port = SerialPort()
    ports = SerialPort().list_ports()
    main = MainGUI()
    for port in ports:
        main.mycombobox.append_text(port)
    main.mycombobox.set_active(0)
    main.toggle.set_label("Connect")
    main.update_table()
    main.show()

串行端口类:

^{pr2}$

Tags: selfgetifobjectmainportdefbuilder
1条回答
网友
1楼 · 发布于 2024-09-27 09:35:15

我相信你的问题更多的是与线程+GUI有关,而不是GTK。在

据我所知,当您修改liststore模型时,后者应该立即更新。所以,应该没有问题。在

你应该用一个基本的GUI线程来更新它。因此,您需要做的是让您的工作线程(串行端口连接线程)将更新发送到主GUI线程,并让它更新treeview。可以使用GLib.idle_add函数计划更新,让GTK在最方便的时候进行更新。在

现在,要在线程之间通信,可以使用^{}模块。在

我不太明白你的代码。所以我将编写一个简单的示例(使用gtk3pygobject,因为您没有指定)。在

import threading
import queue
import gi
gi.require_version('Gtk', '3.0')
gi.require_version('GLib', '2.0')
from gi.repository import Gtk, GLib

def do_work(com_queue):
    # do some work
    com_queue.put("update for your treeview")
    # continue

class MainGUI(object):
    def __init__(self):
        self.com_queue = queue.Queue()
        self.worker_thread = None
        self.liststore = None
        # more gui initialization...

    def launch_worker_thread(self):
        self.worker_thread = threading.Thread(target=do_work, args=(self.com_queue,))
        self.worker_thread.start()
        Glib.timeout_add(1000, self.check_queue) # run check_queue every 1 second

    def check_queue(self):
        if self.worker_thread.is_alive():
            try:
                update = self.com_queue.get()
                GLib.idle_add(self.update_treeview, (update,)) # send tuple
            except queue.Empty:
                pass
            return True # to keep timeout running
        else:
            return False # to end timeout

    def update_treeview(self, update):
        self.liststore.append(update) # here update the treeview model with tuple

if __name__ == "__main__":
    gui = MainGUI()
    Gtk.main()

我希望这有帮助。在

相关问题 更多 >

    热门问题