【问题标题】:How to set an attribute for a whole frame in Python Tkinter?如何在 Python Tkinter 中为整个帧设置属性?
【发布时间】:2022-01-09 09:31:24
【问题描述】:

在这个框架中,我有 5 个按钮。每个按钮都有几乎所有相同的设置。然后我的代码看起来很拥挤,并且需要更长的时间来重现。

homeButton = tk.Button(navFrame,command=lambda:self.switch(homeButton,"homeFrame"),image=home,
                    bg=colour["red"],activebackground=colour["black"],bd=0, cursor="hand2",width=100,height=100)
homeButton.place(x=50,y=150,anchor="center")

taskButton = tk.Button(navFrame,command=lambda:self.switch(taskButton,"taskFrame"),image=tasks,
                    bg=colour["red"],activebackground=colour["black"],bd=0, cursor="hand2",width=100,height=100)
taskButton.place(x=50,y=250,anchor="center")

monitorButton = tk.Button(navFrame,command=lambda:self.switch(monitorButton,"monitorFrame"),image=proxy,
                      bg=colour["red"],activebackground=colour["black"],bd=0, cursor="hand2",width=100,height=100)
monitorButton.place(x=50,y=350,anchor="center")

controllerButton = tk.Button(navFrame, command=lambda:self.switch(controllerButton,"controllerFrame"),image=options,
                        bg=colour["red"], activebackground=colour["black"],bd=0, cursor="hand2",width=100,height=100)
controllerButton.place(x=50,y=450,anchor="center")

settingsButton = tk.Button(navFrame,command=lambda:self.switch(settingsButton,"settingsFrame"),image=settings,
                        bg=colour["red"],activebackground=colour["black"],bd=0, cursor="hand2",width=100,height=100)
settingsButton.place(x=50,y=550,anchor="center")

有没有办法,比如在 css/html 中为这个框架中的所有按钮设置这些设置 (navFrame)。

我看过了,关于这个话题的说法不多。

Tkinter 也很烂,如果有人可以推荐任何更好的 Python GUI 工具,因为它非常限制无法创建圆形按钮。

【问题讨论】:

  • if anyone can recommend any better Python GUI tools as it's very limiting not being able to create rounded buttons.PySimpleGUI 提供了获得圆形按钮的多种方法的示例(Jason 在下面回答并展示了在 PSG 中制作它们的多种方法)。

标签: python tkinter frame


【解决方案1】:

使用选项数据库

在其核心,tkinter 使用称为选项数据库的东西来管理小部件的默认选项。有关选项数据库如何从 tcl/tk 角度工作的出色描述,请参阅Options and Tk - A Beginner's Guide。您必须做一些简单的心理翻译才能将代码示例转换为 python/tkinter,但这并不难。

使用option_add 方法设置选项,可用于任何小部件。你需要给它一个选项模式来描述正在设置的选项以及将获得选项值的小部件名称或类。

如果要在创建框架之前设置值,则需要指定小部件名称。否则,您可以等到小部件创建完成后再使用自动生成的名称。

对于您的情况,我建议您使用名称“navFrame”作为您的小部件名称。然后,您可以在创建小部件之前定义选项。例如:

root.option_add("*navFrame.Label.background", "red")
root.option_add("*navFrame.Label.cursor", "hand2")
root.option_add("*navFrame.Label.width", 100)
root.option_add("*navFrame.Label.height", 100)

您需要确保您的框架具有名称navFrame,您可以在创建框架时执行此操作:

navFrame = tk.Frame(root, name="navFrame")

虽然我已经展示了如何在代码中设置值,但您也可以将所有选项放在一个文件中并一次性加载它们。这是支持主题的一种快速简便的方法,为每个主题提供了自己的选项文件。

many questions and answers on this site处理选项数据库。

使用自定义类

一个更 Pythonic 的解决方案是创建一个自定义类,您可以在其中硬编码您想要的任何默认值。例如,您可能想要创建一个看起来像这样的NavButton 类:

class NavButton(tk.Button):
    def __init__(self, parent, **kwargs):
        kwargs.setdefault("bg", "red")
        kwargs.setdefault("cursor", "hand2")
        ...
        super().__init__(parent, **kwargs)

  

然后您可以像普通按钮一样使用NavButton

homeButton = NavButton(navFrame, text="Home", command=...)
taskButton = NavButton(navFrame, text="Task", command=...)
...

【讨论】:

  • 因为我昨天看到您刚刚回答,我要感谢您提供有关 tkinter 的丰富信息……您的回答总是彬彬有礼、友善、技术准确、教育和广泛。感谢您多年来提供的帮助。
【解决方案2】:

大多数时候,我会尝试使用 kwargs 来定义相同的属性、函数或类来定义相同的动作。喜欢

def navButton(self, key, image, option, index):
    button = tk.Button(navFrame, image=image, **option)
    button.configure(command=lambda:self.switch(button, key))
    x, y = 50, 50 + 100*index
    button.place(x=x, y=y, anchor='center')
    return button

option1 = {
    'bg': colour['red'],
    'activebackground': colour['black'],
    'bd': 0,
    'cursor': 'hand2',
    'width': 100,
    'height': 100,
}

homeButton       = self.navButton("homeFrame",       home,     option1, 1)
taskButton       = self.navButton("taskFrame",       tasks,    option1, 2)
monitorButton    = self.navButton("monitorFrame",    proxy,    option1, 3)
controllerButton = self.navButton("controllerFrame", options,  option1, 4)
settingsButton   = self.navButton("settingsFrame",   settings, option1, 5)

【讨论】:

    【解决方案3】:

    我只是创建了一个为我设置按钮的函数:

    def set_up_buttons(button, x_placement, y_placement, navFrame, image):
            
        button.configure(navFrame, image=image,bg=colour["red"], activebackground=colour["black"], bd=0, cursor="hand2",width=100,height=100)
    
        button.place(x = x_placement, y = y_placement, anchor = "center")
    
    
    homeButton = tk.Button(command=lambda:self.switch(homeButton,"homeFrame"))
    set_up_buttons(homeButton, 50, 150, navFrame, home)
    
    # Do the above two lines for every button that you have.
    
    
    

    我确信有很多更有效的解决方案,但这是我使用的。

    对于您的其他问题,我个人使用 Tkinter,但听说 PyQt 是一个不错的选择,但很先进。 PySimpleGUI 易于实现和推荐。

    【讨论】:

    • 谢谢,我试试看。我见过一些像这样的代码: navFrame.set_attribute(bg="red") 不过似乎从来没有为我工作过。 PyQt5 非常先进,看起来很像 C++,我真的不想去,但我会看看 PySimpleGUI。
    • 那是因为navFrame.set_attribute(bg="red")改变了框架的颜色,而不是框架中的按钮。
    • @SyntaxError:这是不正确的。调用set_attribute 只会设置python 对象的一个​​属性,它不会改变底层小部件的颜色。要配置底层小部件的选项,您需要调用configure 方法。
    • @Bryan Oakley 感谢您让我知道。我混淆了configureset_attribute,你是对的。
    猜你喜欢
    • 2017-07-09
    • 1970-01-01
    • 2019-09-20
    • 2011-04-25
    • 2018-11-14
    • 2018-03-14
    • 2018-08-30
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多