0

我正处于完成程序从 Tkinter 到 Gtk 过渡的最后阶段。最后一步是以有效的方式更新 ListStore。到目前为止,我正在尝试的工作......但在它崩溃之前只有大约 15-120 秒(错误代码是 139;有时是没有其他消息的核心转储,有时是“警告:检测到损坏的双链表” )。在运行时,top报告使用的 RAM 少于 100 MB。

ListStore 包含 51 行 25 列,创建如下:

def init_ListStore():
    # initialize the main ListStore database
    for symbol in cbp_symbols.keys():
        name = cbp_symbols[symbol]['name']
        row = [symbol, name, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
               0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0]
        liststore1.append(row)
    treeview1.set_model(liststore1)

    cell = Gtk.CellRendererText()
    columns = list(my_vars['liststore_main']['column_data'].keys())
    for i in range(liststore1.get_n_columns()):
        treeviewcolumn = Gtk.TreeViewColumn(columns[i])
        treeview1.append_column(treeviewcolumn)
        treeviewcolumn.pack_start(cell, True)
        treeviewcolumn.add_attribute(cell, "text", i)

完成后,我执行以下 (3) 步骤:

更新我的帐户信息(代币余额),从 websocket 获取新消息(存储为字典),逐个单元更新新信息,例如:

liststore1[row][col.index('Open')] = float(ticker_data["open_24h"])
liststore1[row][col.index('Last')] = float(ticker_data["price"])
liststore1[row][col.index('Low')] = float(ticker_data["low_24h"])
liststore1[row][col.index('High')] = float(ticker_data["high_24h"])
liststore1[row][col.index('Volume')] = float(ticker_data["volume_24h"])

我希望能够一次编辑/替换整行;以上似乎缓慢而繁重。完成初始创建/更新后,一切都使用相同的功能完成(每条消息总共要进行大约 20 次更新)。

更新#1:这次我得到了一个更明确的错误。问题出在lib/python3.8/site-packages/gi/overrides/Gtk.py模块第 1680 行:

if GTK2 or GTK3:
    _Gtk_main_quit = Gtk.main_quit

    @override(Gtk.main_quit)
    def main_quit(*args):
        _Gtk_main_quit()

    _Gtk_main = Gtk.main

    @override(Gtk.main)
    def main(*args, **kwargs):
        with register_sigint_fallback(Gtk.main_quit):
            with wakeup_on_signal():
                return _Gtk_main(*args, **kwargs)   << this line

更新#2:我认为这与多线程锁定有关,但我不知道它是如何工作的(模块是由 websocket 客户端导入的,而不是由我导入的)。我确实尝试在解析传入套接字消息的主函数上应用锁定,但它没有帮助。我知道如果我在没有激活 Gtk 窗口的情况下运行程序,它永远不会崩溃。

4

1 回答 1

0

终于得到了这个工作。诀窍是使用 Gtk.TreeIter 引用当前行,然后一次性更新整行:

titer = liststore1.get_iter(row)
my_columns = [
    df.columns.get_loc('Last') + 1,
    df.columns.get_loc('Open') + 1,
    df.columns.get_loc('Change') + 1,
    df.columns.get_loc('Change %') + 1,
    df.columns.get_loc('Low') + 1,
    df.columns.get_loc('High') + 1,
    df.columns.get_loc('Value') + 1,
    df.columns.get_loc('Val Open') + 1,
    df.columns.get_loc('Port %') + 1,
    df.columns.get_loc('Cost Basis') + 1,
    df.columns.get_loc('CB Change') + 1,
    df.columns.get_loc('Value') + 1,
    df.columns.get_loc('Val Open') + 1,
    df.columns.get_loc('Profit') + 1,
    df.columns.get_loc('Volume') + 1,
    df.columns.get_loc('30d Avg') + 1,
    df.columns.get_loc('Vol Act %') + 1,
    df.columns.get_loc('Trade Val') + 1
]
my_data = [
    df.at[row, 'Last'],
    df.at[row, 'Open'],
    df.at[row, 'Change'],
    df.at[row, 'Change %'],
    df.at[row, 'Low'],
    df.at[row, 'High'],
    df.at[row, 'Value'],
    df.at[row, 'Val Open'],
    df.at[row, 'Port %'],
    df.at[row, 'Cost Basis'],
    df.at[row, 'CB Change'],
    df.at[row, 'Value'],
    df.at[row, 'Val Open'],
    df.at[row, 'Profit'],
    df.at[row, 'Volume'],
    df.at[row, '30d Avg'],
    df.at[row, 'Vol Act %'],
    df.at[row, 'Trade Val']
]
liststore1.set(titer, my_columns, my_data)

我知道这段代码需要精简,但我倾向于先让一些东西工作,然后再简化/精简。

于 2021-04-02T17:28:02.457 回答