在 Python 中,使用 ttk Scrollbar 作为 Toplevel() 的子对象时,可能会遇到错误。这与作为 Tk() 的子对象时的情况不同,后者可以正常工作。错误信息通常是:“_tkinter.TclError: can't put .19084144 inside .18651952.19084112\nor... can't put scrollbar inside Toplevel().Frame()”。
2. 解决方案
问题可能在于创建滚动条时没有提供父对象参数。默认情况下,滚动条将被创建在根窗口中。当您尝试将其放在其他顶层窗口中时,就会收到类似于上述的错误。
以下是如何解决此问题的步骤:
- 在创建滚动条时,提供父对象作为参数。例如:
vsb = Scrollbar(treeFrame, orient="vertical", command=self.tree.yview)
- 将滚动条放在正确的容器中。在顶层窗口中,滚动条应该放在一个框架中,而不是直接放在窗口中。例如:
treeFrame = Frame(top)
treeFrame.pack(fill='both', expand=True)
vsb = Scrollbar(treeFrame, orient="vertical", command=self.tree.yview)
vsb.pack(side="right", fill="y")
self.tree.configure(yscrollcommand=vsb.set)
- 确保滚动条的父对象也是窗口的子对象。例如:
top = Toplevel()
treeFrame = Frame(top)
treeFrame.pack(fill='both', expand=True)
vsb = Scrollbar(treeFrame, orient="vertical", command=self.tree.yview)
vsb.pack(side="right", fill="y")
self.tree.configure(yscrollcommand=vsb.set)
treeFrame.grid(column=0, row=0, sticky='nsew', in_=top)
通过这些步骤,您应该能够在 Toplevel() 中使用 ttk Scrollbar,而不会出现错误。
代码示例:
from tkinter import *
from tkinter.ttk import *
class columnList(object):
def __init__(self,parent,header,dataList):
self.tree = None
self._setup_widgets(parent,header)
self._build_tree(header,dataList)
def _setup_widgets(self,parent,header):
treeFrame = Frame(parent)
treeFrame.pack(fill='both', expand=True)
# create a treeview with a vertical scrollbar
self.tree = Treeview(treeFrame, columns=header, show="headings")
vsb = Scrollbar(treeFrame, orient="vertical",command=self.tree.yview)
self.tree.configure(yscrollcommand=vsb.set)
self.tree.grid(column=0, row=0, sticky='nsew', in_=treeFrame)
vsb.grid(column=1, row=0, sticky='ns', in_=treeFrame)
treeFrame.grid_columnconfigure(0, weight=1)
treeFrame.grid_rowconfigure(0, weight=1)
def _build_tree(self,header,dataList):
for col in header:
self.tree.heading(col, text=col.title())
for item in dataList:
self.tree.insert('', 'end', values=item)
# the test data ...
oil_header = ['oil', 'filter', 'cost']
oil_list = [
('synthetic', 'paper', '63.38') ,
('natural', 'reusable', '47.59') ]
car_header = ['car', 'repair', 'cost', 'code']
car_list = [
('Hyundai', 'brakes', '273.80', '34') ,
('Honda', 'light', '85.70', '78')]
root = Tk()
top = Toplevel()
# this succeeds
invoiceMenu = columnList(root,car_header,car_list)
# this fails as
# _tkinter.TclError: can't put .19084144 inside .18651952.19084112
# or... can't put scrollbar inside Toplevel().Frame()
oilChangeMenu = columnList(top,oil_header,oil_list)
root.mainloop()