为什么打包滚动条时Tkinter会冻结?

4 投票
1 回答
1923 浏览
提问于 2025-04-17 04:52

我在用Tkinter给一个列表框加滚动条,但是每次代码运行到.pack()那几行的时候就卡住了……你知道为什么吗?(我试过在网上找到的一个示例代码,那个是可以正常工作的)。

        #Read Box
    self.scrollbar = Tkinter.Scrollbar(self.frame)
    #self.scrollbar.pack(side=Tkinter.RIGHT, fill=Tkinter.Y)
    self.read = Tkinter.Listbox(self.frame, width=50, yscrollcommand=self.scrollbar.set)
    self.read.grid(row=1,column=2)
    #self.read.pack(side=Tkinter.LEFT, fill=Tkinter.BOTH)
    self.scrollbar.config(command=self.read.yview)

你知道为什么这段代码不行吗?


更新后的代码:

        #Read Box
    self.scrollbar = Tkinter.Scrollbar(self.frame)
    self.scrollbar2.grid(sticky=Tkinter.N+Tkinter.S) #row=1, column=2 side=Tkinter.RIGHT, fill=Tkinter.Y

    self.read = Tkinter.Listbox(self.frame, width=50, yscrollcommand=self.scrollbar.set)
    self.read.grid(row=1,column=2) #side=Tkinter.LEFT, fill=Tkinter.BOTH

    self.scrollbar.config(command=self.read.yview)

好吧,那是个小错误(我把滚动条和滚动条2搞混了)。不过现在我有了这段代码:

        #Read Box
    self.scrollbar = Tkinter.Scrollbar(self.frame)
    self.scrollbar.grid(row=1, column=2)

    self.read = Tkinter.Listbox(self.frame, width=50, yscrollcommand=self.scrollbar.set)
    self.read.grid(row=1,column=2)

    self.scrollbar.config(command=self.read.yview)

这段代码不会卡住,滚动条也出现了,但它们和列表框没有连接(也没有控制列表框的功能)。至于其他代码,都是grid语句,没有用pack。


我找到了问题,滚动条缺少sticky=Tkinter.N+Tkinter.S。下面是完成的代码(还加了水平滚动条)。

        #Read Box
    self.scrollbar = Tkinter.Scrollbar(self.frame)
    self.scrollbar.grid(row=1, column=3, sticky=Tkinter.N+Tkinter.S)

    self.hbar = Tkinter.Scrollbar(self.frame, orient=Tkinter.HORIZONTAL)
    self.hbar.grid(row=2, column=2, sticky=Tkinter.E+Tkinter.W)

    self.read = Tkinter.Listbox(self.frame, width=50, yscrollcommand=self.scrollbar.set, xscrollcommand=self.hbar.set)
    self.read.grid(row=1,column=2)

    self.scrollbar.config(command=self.read.yview)
    self.hbar.config(command=self.read.xview)

1 个回答

2

看起来你把 packgrid 放在了同一个层级(也就是说,没有放在两个不同的 Frame 里)。这样会导致你的应用程序卡住,正如文档中所描述的那样。

所以你应该把你的滚动条用 .grid 来布局 :-)

补充说明:正如上面所说,你可以混合使用不同的窗口管理器,但不能在同一个框架内混用。下面的代码是合法的,并且可以正常工作:

from Tkinter import *
root = Tk()
f1 = Frame(root)
f1.pack()
Label(f1, text='some text').grid(row=0, column=0)
Button(f1, text='Button').grid(row=1, column=0)

f2 = Frame(root)
f2.pack()
Label(f2, text="content of Frame 2").pack()

root.mainloop()

撰写回答