如何在 Tkinter 中创建带有滚动条的 LabelFrame?

发布于 2024-11-30 05:31:42 字数 1366 浏览 1 评论 0原文

我正在使用 Python 和 Tkinter 为我正在编写的程序创建 GUI,但遇到了一些问题。

我在从 Frame 派生的对象中拥有从 LabelFrame 派生的三个对象。 LabelFrame 后代之一是两列相应的 Label 和 Entry 对象。

freq_frame example

问题是标签和条目对的数量不同,并且可能超出了适合的范围。屏幕。我需要一种方法来为此 LabelFrame 制作滚动条,以便所有内容都适合屏幕。我尝试了各种制作 Scrollbar 对象的方法,但似乎没有任何效果。如何将滚动条绑定到该框架?

另外,当调用 load_message() 方法时,我需要能够刷新或重新加载此 LabelFrame,但它只是在旧的对之上重新显示新对(因此,当新集,旧集在底部仍然可见)。我尝试过使用 grid_forget() ,但要么没有任何变化,要么整个框架不显示。我怎样才能忘记这个显示然后重新显示它?

这是此类的代码:

class freq_frame(LabelFrame):
    def __init__(self, master = None, text = 'Substitutions'):
        LabelFrame.__init__(self, master, text = text)
        self.grid()
    def load_message(self):
        self.frequency = get_freq(message)
        self.create_widgets()
    def create_widgets(self):
        self.label_list = [Label(self, text = get_label(char, self.frequency[char]), justify = LEFT) for char in self.frequency.keys()]
        self.entry_list = [Entry(self, width = 1) for char in self.frequency.keys()]
        for n in range(len(self.label_list)):
            self.label_list[n].grid(column = 0, row = n)
        for n in range(len(self.entry_list)):
            self.entry_list[n].grid(column = 1, row = n)

如果有人可以帮助解决这些问题,我将不胜感激。

另外,这个问题好像有点薄,但我不知道该补充什么。请随时询问更多信息(但要具体)。

谢谢!

I'm using Python and Tkinter to create a GUI for a program I'm writing, and I'm having a couple of problems.

I have three objects descended from LabelFrame in an object descended from Frame. One of the LabelFrame descendants is two columns of corresponding Label and Entry objects.

freq_frame example

The problem is that there are a varying number of Label and Entry pairs, and there can be more than fit on the screen. I need a way to make a scrollbar for this LabelFrame so that everything fits on the screen. I've tried various ways of making a Scrollbar object, but nothing seems to work. How can I bind a scrollbar to this frame?

Also, I need to be able to refresh or reload this LabelFrame when the load_message() method is called, but it just redisplays the new pairs on top of the old ones (so when there are less pairs in the new set, the old set is still visible at the bottom). I've tried using grid_forget() but either nothing changes or the whole frame doesn't display. How can I forget this display and then redisplay it?

Here is the code for this class:

class freq_frame(LabelFrame):
    def __init__(self, master = None, text = 'Substitutions'):
        LabelFrame.__init__(self, master, text = text)
        self.grid()
    def load_message(self):
        self.frequency = get_freq(message)
        self.create_widgets()
    def create_widgets(self):
        self.label_list = [Label(self, text = get_label(char, self.frequency[char]), justify = LEFT) for char in self.frequency.keys()]
        self.entry_list = [Entry(self, width = 1) for char in self.frequency.keys()]
        for n in range(len(self.label_list)):
            self.label_list[n].grid(column = 0, row = n)
        for n in range(len(self.entry_list)):
            self.entry_list[n].grid(column = 1, row = n)

If anyone can help with either of these problems, I'd appreciate it.

Also, this question seems like it might be a little thin, but I don't know what to add. Don't hesitate to ask for more information (but be specific).

Thanks!

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

梦忆晨望 2024-12-07 05:31:42

Labelframes 不支持滚动。所以你的问题的简短答案是“你不能”。这听起来很明显,但如果小部件的文档没有说它支持滚动,那么它就不支持滚动。

然而,有一个简单的解决方案。首先,将画布作为子项添加到标签框架中并将其打包,以便它填充标签框架。将滚动条附加到画布并将它们也添加到标签框架中。然后在画布中嵌入一个框架,将小部件添加到该内部框架,然后在添加所有内部标签和条目后调整画布的滚动区域以匹配框架的大小。

听起来很复杂,但实际上非常简单。

至于在调用load_message时重新创建小部件,调用grid_forget只会将它们从视图中删除,实际上并不会销毁小部件。随着时间的推移,您可能会得到数百个不可见的小部件,这几乎肯定不是您想要的。

相反,您希望首先销毁所有现有的小部件。如果它们都在同一个父级中,那么这很容易,因为您可以向父级询问其所有子级的列表。只需迭代该列表即可删除每个子项,然后添加任何新的子项。一个更简单的解决方案是销毁并重新创建包含标签和条目的内部框架。当您删除小部件时,所有子小部件都会自动销毁。因此,删除该内部框架,创建一个新框架,然后再次添加标签和条目。

Labelframes don't support scrolling. So the short answer to your question is "you can't". It sounds obvious, but if the documentation for a widget doesn't say it supports scrolling, it doesn't support scrolling.

However, there is a simple solution. First, add a canvas as a child to the labelframe and pack it so that it fills the labelframe. Attach scrollbars to the canvas and add them to the labelframe too. Then embed a frame within the canvas, add your widgets to that inner frame, and then adjust the scrollregion of the canvas to match the size of the frame after you've added all the inner labels and entries.

It sounds complicated, but it's really very straight-forward.

As for re-creating the widgets when you call load_message, calling grid_forget only removes them from view, it doesn't actually destroy the widgets. Over time you could potentially end up with hundreds of non-visible widgets which is almost certainly not what you want.

Instead, you want to first destroy all the existing widgets. That's pretty easy if they all are in the same parent, since you can ask the parent for a list of all its children. Just iterate over that list to delete each child, then add any new children. An even easier solution is to destroy and recreate that inner frame that contains the labels and entries. When you delete a widget, all child widgets get automatically destroyed. So, delete that inner frame, create a new one, and add your labels and entries again.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文