我有一个python脚本,可创建一个带有垂直滚动条的显示数字网格的窗口。我遇到的问题是滚动过于生涩且不流畅。有什么办法可以克服吗?一个测试示例是:
import tkinter as tk
class list_window(tk.Toplevel):
def __init__(self, title, *args, **kwargs):
tk.Toplevel.__init__(self, None, *args, **kwargs)
self.title(title)
self.geometry('1500x600')
self.outer_frame=tk.Frame(self)
canvas=tk.Canvas(self.outer_frame)
self.list_frame=tk.Frame(canvas)
scrollbar = tk.Scrollbar (self.outer_frame,orient="vertical",command=canvas.yview)
canvas.configure(yscrollcommand=scrollbar.set, yscrollincrement=10)
def scrollhelper(event):
canvas.configure(scrollregion=canvas.bbox("all"))
self.list_frame.bind("<Configure>",scrollhelper)
self.outer_frame.pack(side="top",fill="both",expand=1)
scrollbar.pack(side="right",fill="y")
canvas.pack(side="left",fill="both",expand=1)
canvas.create_window((0,0),window=self.list_frame,anchor='nw')
#Fill with a bunch of widgets, for example
import random
for i in range(1000):
for j in range(10):
tk.Label(self.list_frame, text=str(random.random())).grid(row=i, column=j)
def spawn_list_window():
win = list_window("My list window")
root = tk.Tk()
win = list_window("My List")
root.mainloop()
答案 0 :(得分:2)
import tkinter as tk
from tkinter import ttk
class Treeview(ttk.Treeview):
def __init__(self, master, headings: list, col_widths: list = None, binds: dict = None):
super().__init__(master=master, columns=headings, show="headings")
self.col_widths = [] if col_widths is None else col_widths
self.scroll = ttk.Scrollbar(self)
self.configure(yscrollcommand=self.scroll.set)
self.scroll.configure(command=self.yview)
# Bind events to commands
if isinstance(binds, dict):
for k, v in binds.items():
try:
self.bind(f"<{k}>", v)
except tk.TclError:
self.bind(f"{k}", v)
self.reset()
self.scroll.pack(side=tk.RIGHT, fill=tk.Y)
# Append rows to the treeview
def populate(self, data, top_down=False):
for i, d in enumerate(data):
self.insert("", 0 if top_down else "end", values = d)
# Clears the entire tree
def clear(self):
self.delete(*self.get_children())
def reset(self):
for i, col in enumerate(self["columns"]):
self.heading(col, text=col)
if i < len(self.col_widths):
self.column(col, minwidth=self.col_widths[i], width=self.col_widths[i], stretch=tk.NO)
# Returns the first value which was selected
def one(self):
try:
item = self.item(self.selection()[0])["values"]
except IndexError: # Normally this happens if the item selected is the column header
return None
else:
return item
使用ttk.Treeview
可以更轻松地完成您要尝试的操作。上一类是围绕它的包装,在需要时可以使用。
下面的代码是使用它的示例。
root = tk.Tk()
tree = Treeview(root, [f"Heading {i+1}" for i in range(10)])
data = []
for i in range(1000):
data.append([])
for j in range(10):
data[-1].append(random.random())
tree.populate(data)
tree.pack(expand=True, fill=tk.BOTH)
root.mainloop()