GtkTreeView 停止更新,除非我更改 window 的焦点

GtkTreeView stops updating unless I change the focus of the window

我有一个使用 GtkListStore 模型的 GtkTreeView 对象,该模型不断更新如下:

  1. 获取新交易
  2. 将数据输入 numpy 数组
  3. 将数字转换为格式化字符串,存储在pandas dataframe
  4. 通过GtkListStore.set(titer, liststore_cols, liststore_data)将更新的令牌信息添加到GtkListStore),其中liststore_data是更新的信息,liststore_cols是列的名称(都是列表)。

这是更新 ListStore 的函数:

# update ListStore
titer = ls_full.get_iter(row)
liststore_data = []
[liststore_data.append(df.at[row, col])
 for col in my_vars['ls_full'][3:]]
# check for NaN value, add a (space) placeholder is necessary
for i in range(3, len(liststore_data)):
    if liststore_data[i] != liststore_data[i]:
        liststore_data[i] = " "
liststore_cols = []
[liststore_cols.append(my_vars['ls_full'].index(col) + 1)
 for col in my_vars['ls_full'][3:]]
ls_full.set(titer, liststore_cols, liststore_data)

Class 从 websocket 获取消息:

class MyWebsocketClient(cbpro.WebsocketClient):
    # class exceptions to WebsocketClient
    def on_open(self):
        # sets up ticker Symbol, subscriptions for socket feed
        self.url = "wss://ws-feed.pro.coinbase.com/"
        self.channels = ['ticker']
        self.products = list(cbp_symbols.keys())

    def on_message(self, msg):
        # gets latest message from socket, sends off to be processed
        if "best_ask" and "time" in msg:
            # checks to see if token price has changed before updating
            update_needed = parse_data(msg)
            if update_needed:
                update_ListStore(msg)
        else:
            print(f'Bad message: {msg}')

程序第一次启动时,更新是一致的。每次有新交易进入时,屏幕都会反映出来,更新适当的令牌。然而,经过一段随机的时间——从 5 分钟到一个多小时的任何时间——屏幕将停止更新,除非我改变 window 的焦点(激活或不激活)。不过,这不会持续很长时间(只够更新屏幕一次)。没有报告其他错误,内存使用量没有激增(恒定为 140 MB)。

我该如何解决这个问题?我什至不知道从哪里开始。数据后端似乎没问题(数据永远不会损坏也不会滞后)。

正如您在评论中所说,它是 运行 在一个单独的线程中,那么我建议用 GLib.idle_add.

包装您的“更新列表存储”功能
from gi.repository import GLib
GLib.idle_add(update_liststore)

我过去遇到过类似的问题,现在已经解决了。有时更新liststore没问题,有时会随机喷出错误。

基本上一次只有一个线程应该更新 GUI。因此,通过包装在 GLib.idle_add() 中,您可以确保您的后台线程不会干扰更新 GUI 的主线程。