如何在Tkinter中使用滚动条创建LabelFrame? [英] How do you create a LabelFrame with a scrollbar in Tkinter?

查看:394
本文介绍了如何在Tkinter中使用滚动条创建LabelFrame?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

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

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

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

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.

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

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?

此外,调用load_message()方法时,我需要能够刷新或重新加载此LabelFrame,但它只是在旧的对上重新显示新的对(因此,在新集中的对较少时,旧集仍在底部可见).我试过使用grid_forget(),但是没有任何变化或整个框架都没有显示.如何忘记此显示然后重新显示?

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?

这是此类的代码:

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).

谢谢!

推荐答案

标签框架不支持滚动.因此,对您的问题的简短回答是您不能".听起来很明显,但是如果小部件的文档未说它支持滚动,则它不支持滚动.

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.

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

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.

至于在调用load_message时重新创建窗口小部件,调用grid_forget只会从视图中删除它们,实际上并不会破坏窗口小部件.随着时间的流逝,您最终可能会获得数百个不可见的小部件,这几乎肯定不是您想要的.

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.

这篇关于如何在Tkinter中使用滚动条创建LabelFrame?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆