【发布时间】:2021-06-18 13:50:18
【问题描述】:
Tkinter 中的 canvas Widget 绘制速度非常慢,即使使用有限的小部件,在滚动时也会对应用程序视觉造成很大的失真。
我已经四处搜索,但似乎只有人们在画布上绘制多个东西而不是滚动条效果的答案。
我的代码是否有任何问题会导致此问题,或者是否有任何方法可以修复绘制时间以在视觉上更加流畅。在应用程序中,这意味着每一行都是不同的颜色,这可能会使其非常难看,并且很难找到用户正在寻找的数据。
MVCE:
#python 3.8.6
from tkinter import *
import random
class test:
def __init__(self):
self.words = ["troop","relieve","exact","appeal","shortage","familiar","comfortable","sniff","mold","clay","rack","square","color","book","velvet","address","elaborate","grip","neutral","pupil"]
def scrollable_area2(self, holder):
base_frame = Frame(holder, padx=5, pady=5)
base_frame.pack(fill=BOTH, expand=1)
base_frame.rowconfigure(0, weight=0)
base_frame.columnconfigure(0, weight=1)
can = Canvas(base_frame, bg="white")
can.pack(side=LEFT, expand=1, fill=BOTH)
scrollArea = Frame(base_frame, bg="white", )
scrollArea.pack(side=LEFT, expand=1, fill=BOTH)
can.create_window(0, 0, window=scrollArea, anchor='nw')
Scroll = Scrollbar(base_frame, orient=VERTICAL)
Scroll.config(command=can.yview)
Scroll.pack(side=RIGHT, fill=Y)
can.config(yscrollcommand=Scroll.set)
scrollArea.bind("<Configure>", lambda e=Event(), c=can: self.update_scrollregion(e, c))
return scrollArea, can
def update_scrollregion(self, event, can):
if can.winfo_exists():
can.configure(scrollregion=can.bbox("all"))
def generate(self, count): #generates the rows
for i in range(int(count.get())):
row = Frame(self.holder)
row.pack(side=TOP)
for i in range(9):
a = Label(row, text=self.words[random.randint(0, len(self.words)-1)])
a.pack(side=LEFT)
b = Button(row, text=self.words[random.randint(0, len(self.words)-1)])
b.pack(side=LEFT)
def main(self):
opts = Frame(self.root)
opts.pack(side=TOP)
v= StringVar()
e = Entry(opts, textvariable=v)
e.pack(side=LEFT)
b=Button(opts, text="Run", command=lambda e=Event(), v=v:self.generate(v))
b.pack(side=LEFT)
main_frame=Frame(self.root)
main_frame.pack(side=TOP, fill=BOTH, expand=1)
self.holder, can = self.scrollable_area2(main_frame)
def run(self):
self.root = Tk()
self.main()
self.root.mainloop()
if __name__ == "__main__":
app = test()
app.run()
我留下了一个框,您可以在其中输入行数。我尝试了从 30 行到 300 多行,尽管初始渲染时间发生了变化,但滚动问题始终相同。
注意:对于我创建滚动区域的奇怪方式感到抱歉,它来自一段更复杂的代码,如果这最终成为一个因素,我已经对其进行了修改以适应此处。
【问题讨论】:
-
如果您要创建垂直堆栈的小部件,使用文本小部件可能比使用画布和嵌入式框架更有效。
-
我的代码是创建一个表,每行有 10-15 列和一个按钮。不确定文本小部件是否可以做与画布和框架组合相同的事情。
-
好吧,公平地说,您的示例没有创建表。您当然可以在文本小部件中以表格形式排列内容。
-
您可以像添加框架一样向文本小部件添加小部件
标签: python-3.x tkinter tkinter-canvas