You need to enable JavaScript to run this app.
最新活动
大模型
产品
解决方案
定价
生态与合作
支持与服务
开发者
了解我们

如何控制带Scrollbar的Tkinter Treeview是否更新显示以提升性能

控制Treeview的UI更新开关

首先,你的核心需求是暂停/恢复Treeview的内容更新,避免频繁修改导致的UI卡顿。Tkinter确实会在你修改Treeview元素(比如调用item()方法)时自动触发屏幕刷新,我们可以通过一个状态标志来控制是否执行实际的更新操作,同时保留更新逻辑的运行(或者也可以暂停整个更新循环,看你需求)。

下面是修改后的完整代码,我会一步步解释关键改动:

from tkinter.ttk import * 
from tkinter import * 

root = Tk() 
root.geometry('800x800') 
root.bind('<Escape>', lambda x:root.destroy() ) 

class Run_item_Tree(Frame): 
    def __init__(self, roots): 
        Frame.__init__(self, roots) 
        t = Treeview(self, selectmode=NONE, height=10) 
        self.t = t 
        t["columns"] = ("1", "2") 
        t['show'] = 'headings' 
        t.column("1", width=100, anchor='c') 
        t.column("2", width=50, anchor='c') 
        t.heading("1", text="Title") 
        t.heading("2", text="UL") 
        t.pack(fill =BOTH,side =LEFT) 
        vsb = Scrollbar(self, orient="vertical", command=t.yview) 
        vsb.pack(fill = Y,side = RIGHT) 
        self.vsb = vsb 
        t.configure(yscrollcommand=vsb.set) 
        # 添加更新启用标志,默认开启
        self.update_enabled = True
        self.pack() 

a = Run_item_Tree(root) 
item_num = 4000 
for i in range(item_num): 
    # 修正values数量,和定义的列数匹配
    a.t.insert('',index=END,text = i,values = (i,i+1),tags=('pass',))  

count = 0 

def update_test(): 
    global count 
    # 只有启用更新时才修改Treeview内容
    if a.update_enabled:  
        a.t.item(a.t.get_children()[0],values = (count,count+1)) 
    count= (count+1)%item_num 
    root.after(100, update_test) 

def toggle_update():
    # 切换更新状态
    a.update_enabled = not a.update_enabled
    # 更新按钮文本,提示当前状态
    btn['text'] = '暂停更新' if a.update_enabled else '恢复更新'

btn = Button(root,text='暂停更新',command=toggle_update) 
btn.pack() 

root.after(100,update_test) 
root.mainloop()

关键改动说明:

  • Run_item_Tree类中添加了self.update_enabled布尔变量,用来标记是否允许Treeview更新UI。
  • 实现了toggle_update函数作为按钮回调:它会切换update_enabled的状态,同时更新按钮文本让用户直观了解当前状态。
  • update_test函数中增加判断:只有当update_enabledTrue时,才执行a.t.item()的修改操作——暂停期间,count依然会递增,但不会触发Treeview的UI刷新,避免了不必要的性能消耗。

扩展:线程场景下的控制

如果你是在子线程中修改Treeview内容,记住Tkinter的UI操作必须在主线程执行,子线程不能直接调用item()方法。你可以通过主线程的after()方法传递修改请求,同时用update_enabled标志过滤这些请求:

import threading
import time

def thread_update():
    global count
    while True:
        time.sleep(0.1)
        count = (count+1)%item_num
        # 把修改请求放到主线程执行,同时判断更新状态
        if a.update_enabled:
            root.after(0, lambda: a.t.item(a.t.get_children()[0],values=(count,count+1)))

这样即使子线程在运行,只要update_enabledFalse,就不会触发Treeview的UI更新,避免卡顿。

内容的提问来源于stack exchange,提问作者黃瀚嶙

火山引擎 最新活动