Python ttk Scrollbar 错误作为 Toplevel() 的子对象,但作为 Tk() 的子对象可行

117 阅读2分钟

在 Python 中,使用 ttk Scrollbar 作为 Toplevel() 的子对象时,可能会遇到错误。这与作为 Tk() 的子对象时的情况不同,后者可以正常工作。错误信息通常是:“_tkinter.TclError: can't put .19084144 inside .18651952.19084112\nor... can't put scrollbar inside Toplevel().Frame()”。

huake_00152_.jpg

2. 解决方案

问题可能在于创建滚动条时没有提供父对象参数。默认情况下,滚动条将被创建在根窗口中。当您尝试将其放在其他顶层窗口中时,就会收到类似于上述的错误。

以下是如何解决此问题的步骤:

  1. 在创建滚动条时,提供父对象作为参数。例如:
vsb = Scrollbar(treeFrame, orient="vertical", command=self.tree.yview)
  1. 将滚动条放在正确的容器中。在顶层窗口中,滚动条应该放在一个框架中,而不是直接放在窗口中。例如:
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)
  1. 确保滚动条的父对象也是窗口的子对象。例如:
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()