GtkTreeView 停止更新,除非我改变窗口的焦点

问题描述

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

  1. 获取新交易
  2. 将数据输入 numpy 数组
  3. 将数字转换为格式化字符串,存储在 Pandas 数据帧中
  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_data)

从 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 分钟到一个多小时的任何地方看到它——屏幕将停止更新,除非我改变窗口的焦点(激活或非活动)。但是,这不会持续很长时间(仅足以更新屏幕一次)。没有报告其他错误,内存使用量没有激增(恒定为 140 MB)。

我该如何解决这个问题?我什至不确定从哪里开始。数据后端似乎还可以(数据从未损坏或滞后)。

解决方法

正如您在评论中所说,它在单独的线程中运行,那么我建议您使用 GLib.idle_add 包装您的“更新列表存储”函数。

from gi.repository import GLib
GLib.idle_add(update_liststore)

我过去也遇到过类似的问题,这已经解决了。有时候更新liststore没问题,有时候会随机报错。

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