Python、tkinter 和网格中的滚动条
Python, tkinter and the scrollbar in a grid
我正在尝试获取带有滚动条的列表框。我在这个网站上阅读了大约 20 个其他答案,none 似乎适合我的情况,所以我不得不问自己。
我有一个 LabelFrame 小部件,其中有一些标签和一个 ListBox 小部件。我希望 ListBox 小部件具有滚动条。我似乎无法让它工作。
这是有问题的代码:
self.lbDates = tk.Listbox(master=group, width=12)
self.lbDates.grid(row=3, column=1, padx=3, pady=3)
self.scrollDates = tk.Scrollbar(self.lbDates, orient="vertical")
self.scrollDates.config(command=self.lbDates.yview)
self.scrollDates.grid(row=3, column=1)
self.lbDates.config(yscrollcommand=self.scrollDates.set)
几个问题:滚动条是否应该与 ListBox 小部件位于相同的 space(即相同的网格行和列)?我想它应该是,但考虑到我在这方面遇到了多少麻烦,我觉得我应该问一下。
我应该说列表框是通过在别处按下按钮来填充的。没有滚动条,这个日期是正确填充的,所以我假设问题不存在。
当我 运行 这段代码时会发生什么?好吧,我没有看到 ListBox,但我看到了滚动条。现在,当那里应该有数据时(我知道,因为我填充了它),我看到你可能想象的是正确的滚动条,尽管 ListBox 是不可见的或隐藏的或其他东西。当它被填充时,它会闪烁几分之一秒,然后再次隐藏。
我可以给你看一个例子。
上面一个没有数据进来,第二个有数据进来。当然你看不到数据,但是你可以看到它应该是有的。如果我删除滚动条,我确实会在 ListBox 小部件中获得我期望的数据。我想显示它在消失之前填充的那一刻的图像,但它看起来像一个单一的帧,我无法捕捉到它。
我敢肯定我的错误在这里一定很简单,我非常希望有人能提供帮助。我正在为小部件使用 tkinter 和 Python 3.7.
编辑:我已经按照下面的建议进行了一些更改,因此我的 ListBox 和 Scrollbar 现在存在于一个框架中,并且该框架位于 LabelFrame 对象中。如下:
fr = tk.Frame(master = group)
fr.grid(row=4, column=1)
self.lbDates = tk.Listbox(master=fr, width=12)
self.lbDates.pack()
self.scrollDates = tk.Scrollbar(master=self.lbDates, orient="vertical")
self.scrollDates.config(command=self.lbDates.yview)
self.scrollDates.pack()
self.lbDates.config(yscrollcommand=self.scrollDates.set)
不幸的是,没有区别,我似乎遇到了与以前完全相同的问题。
is the scrollbar supposed to be in the same space (i.e. the same grid row and column) as the ListBox widget?
由你决定。通常,您 而不是 将滚动条放在列表框中,因为它会遮盖列表框中的某些数据。列表框和滚动条将具有相同的父项。如果您使用 grid
,通常垂直滚动条属于列表框右侧的列。
What happens when I run this code? Well I don't see a ListBox, but I to see the scroll bar.
这是因为列表框会缩小以适合其子项。列表框在那里,但它只和滚动条一样宽和高。这是您不应该将滚动条放在列表框中的另一个原因。
如果您希望滚动条看起来就像在列表框内一样,最好的做法是创建一个包含列表框和滚动条的框架。
你可以让frame凹陷而listbox变平,这样会让人产生滚动条在listbox内部的错觉。然后您可以将该框架放在 UI 中您喜欢的任何位置,滚动条将始终与列表框一起出现。
列表框和滚动条都需要是框架的子项才能工作。
这是一个简单的例子:
import tkinter as tk
root = tk.Tk()
lb_frame = tk.Frame(root, bd=1, relief="sunken")
listbox = tk.Listbox(lb_frame, bd=0, yscrollcommand=lambda *args: vsb.set(*args))
vsb = tk.Scrollbar(lb_frame, orient="vertical", command=listbox.yview)
vsb.pack(side="right", fill="y")
listbox.pack(side="left", fill="both", expand=True)
lb_frame.pack(padx=20, pady=20)
for i in range(1, 100):
listbox.insert("end", f"Item {i}")
root.mainloop()
我正在尝试获取带有滚动条的列表框。我在这个网站上阅读了大约 20 个其他答案,none 似乎适合我的情况,所以我不得不问自己。
我有一个 LabelFrame 小部件,其中有一些标签和一个 ListBox 小部件。我希望 ListBox 小部件具有滚动条。我似乎无法让它工作。
这是有问题的代码:
self.lbDates = tk.Listbox(master=group, width=12)
self.lbDates.grid(row=3, column=1, padx=3, pady=3)
self.scrollDates = tk.Scrollbar(self.lbDates, orient="vertical")
self.scrollDates.config(command=self.lbDates.yview)
self.scrollDates.grid(row=3, column=1)
self.lbDates.config(yscrollcommand=self.scrollDates.set)
几个问题:滚动条是否应该与 ListBox 小部件位于相同的 space(即相同的网格行和列)?我想它应该是,但考虑到我在这方面遇到了多少麻烦,我觉得我应该问一下。
我应该说列表框是通过在别处按下按钮来填充的。没有滚动条,这个日期是正确填充的,所以我假设问题不存在。
当我 运行 这段代码时会发生什么?好吧,我没有看到 ListBox,但我看到了滚动条。现在,当那里应该有数据时(我知道,因为我填充了它),我看到你可能想象的是正确的滚动条,尽管 ListBox 是不可见的或隐藏的或其他东西。当它被填充时,它会闪烁几分之一秒,然后再次隐藏。
我可以给你看一个例子。
上面一个没有数据进来,第二个有数据进来。当然你看不到数据,但是你可以看到它应该是有的。如果我删除滚动条,我确实会在 ListBox 小部件中获得我期望的数据。我想显示它在消失之前填充的那一刻的图像,但它看起来像一个单一的帧,我无法捕捉到它。
我敢肯定我的错误在这里一定很简单,我非常希望有人能提供帮助。我正在为小部件使用 tkinter 和 Python 3.7.
编辑:我已经按照下面的建议进行了一些更改,因此我的 ListBox 和 Scrollbar 现在存在于一个框架中,并且该框架位于 LabelFrame 对象中。如下:
fr = tk.Frame(master = group)
fr.grid(row=4, column=1)
self.lbDates = tk.Listbox(master=fr, width=12)
self.lbDates.pack()
self.scrollDates = tk.Scrollbar(master=self.lbDates, orient="vertical")
self.scrollDates.config(command=self.lbDates.yview)
self.scrollDates.pack()
self.lbDates.config(yscrollcommand=self.scrollDates.set)
不幸的是,没有区别,我似乎遇到了与以前完全相同的问题。
is the scrollbar supposed to be in the same space (i.e. the same grid row and column) as the ListBox widget?
由你决定。通常,您 而不是 将滚动条放在列表框中,因为它会遮盖列表框中的某些数据。列表框和滚动条将具有相同的父项。如果您使用 grid
,通常垂直滚动条属于列表框右侧的列。
What happens when I run this code? Well I don't see a ListBox, but I to see the scroll bar.
这是因为列表框会缩小以适合其子项。列表框在那里,但它只和滚动条一样宽和高。这是您不应该将滚动条放在列表框中的另一个原因。
如果您希望滚动条看起来就像在列表框内一样,最好的做法是创建一个包含列表框和滚动条的框架。
你可以让frame凹陷而listbox变平,这样会让人产生滚动条在listbox内部的错觉。然后您可以将该框架放在 UI 中您喜欢的任何位置,滚动条将始终与列表框一起出现。
列表框和滚动条都需要是框架的子项才能工作。
这是一个简单的例子:
import tkinter as tk
root = tk.Tk()
lb_frame = tk.Frame(root, bd=1, relief="sunken")
listbox = tk.Listbox(lb_frame, bd=0, yscrollcommand=lambda *args: vsb.set(*args))
vsb = tk.Scrollbar(lb_frame, orient="vertical", command=listbox.yview)
vsb.pack(side="right", fill="y")
listbox.pack(side="left", fill="both", expand=True)
lb_frame.pack(padx=20, pady=20)
for i in range(1, 100):
listbox.insert("end", f"Item {i}")
root.mainloop()