为tkinter小部件创建一个类来调用默认属性

2024-05-19 14:01:03 发布

您现在位置:Python中文网/ 问答频道 /正文

我正在尝试使用Python3中的tkinter创建一个GUI,它将有几个按钮,我不想每次都为所有按钮键入相同的属性,如下所示:

tkinter.Button(topFrame, font=("Ariel", 16), width=10, height=10,
               fg="#ffffff", bg="#000000", text="Cake")

例如,每个按钮上的fgbg颜色和size都是相同的。每个按钮上唯一改变的是文本和在屏幕上放置它们的位置。你知道吗

我对编程和Python非常陌生,当我想创建一个新按钮时,我正在尝试重用代码。我想我错过了一些课程的理解,当我读到它的时候,我没有得到。你知道吗

我想为每个按钮传递不同的文本和不同的框架,以便将其放置在GUI上的不同位置,并使其他内容相同。你知道吗

到目前为止我的代码是:

import tkinter
import tkinter.messagebox

window = tkinter.Tk()

#create default values for buttons
#frame and buttonText are the values passed to the class when making a new
#button
class myButtons:
     def buttonLayout(self, frame, buttonText):
          self.newButton=tkinter.Button(frame, font=("Ariel", 16),
                                        width=10, height=10, fg=#ffffff,
                                        bg=#000000, text=buttonText)

topFrame = tkinter.Frame(window)
topFrame.pack()

#create new button here and place in the frame called topFrame with the text
#"Cake" on it
buttonCake = myButtons.buttonLayout(topFrame, "Cake")
#position the new button in a certain cell using grid in topFrame
buttonCake.grid(row=1, column=0)

window.mainloop()

我尝试运行它时遇到的错误是:

TypeError: buttonLayout() missing 1 required positional argument: 'buttonText'

我很困惑,因为我传递的是"Cake",错误显示它丢失了。你知道吗

感谢您指出init我不知道如何使用init解决我的问题,但这和这里给出的答案都有所帮助。非常感谢。你知道吗


Tags: thetextinnewtkinterbuttonwindow按钮
3条回答

您没有正确定义和使用类。
下面是一个版本,其中包含使其正常工作所需的更正:

import tkinter


class MyButton:
    """ Create Button with some default values. """
    def __init__(self, frame, buttonText):
        self.newButton = tkinter.Button(frame, font=("Ariel", 16),
                                        width=10, height=10, fg='#ffffff',
                                        bg='#000000', text=buttonText)

window = tkinter.Tk()
topFrame = tkinter.Frame(window)
topFrame.pack()

# Create new button here and place in the frame called topFrame with the text
# "Cake" on it.
buttonCake = MyButton(topFrame, "Cake")

# Position the new button in a certain cell in topFrame using grid().
buttonCake.newButton.grid(row=1, column=0)

window.mainloop()

更新

一种更object-oriented的方法是派生您自己的tkinter.Buttonsubclass,这将允许它的实例由于继承而完全像基类的实例一样被利用,也就是说,因此不需要记住在grid()调用中引用它的newButton属性,而不是通常需要的按钮本身。你知道吗

下面所示的实现也非常灵活,在创建一个默认值时,只需通过通常的关联关键字参数为其提供不同的值,就可以轻松地覆盖任何默认值。你知道吗

import tkinter


class MyButton(tkinter.Button):
    """ Create Button with some default values. """

    # Default Button options (unless overridden).
    defaults = dict(font=("Ariel", 16), width=10, height=10,
                    fg='#ffffff', bg='#000000')

    def __init__(self, *args, **kwargs):
        kwargs = dict(self.defaults, **kwargs)  # Allow defaults to be overridden.
        super().__init__(*args, **kwargs)


window = tkinter.Tk()
topFrame = tkinter.Frame(window)
topFrame.pack()

# Create new button here and place in the frame called topFrame with the text
# "Cake" on it.
buttonCake = MyButton(topFrame, text="Cake")

# Position the new button in a certain cell in topFrame using grid().
buttonCake.grid(row=1, column=0)

window.mainloop()

所以我对代码进行了注释,这样你可以学到一些东西

from tkinter import * #in order not to have to writer "tkinter." each time

class app: #we usually put the whole app in a class

    def __init__(self,window): # so here you "attach" things to your instance represented by self
        self.window=window
        self.topFrame = Frame(window)
        self.topFrame.pack()
        self.ButtonList=[]  #because you wouldn't want to make 100 button with the same name

    def buttonLayout(self, frame, buttonText): # here we create a method wich will be also "attached" to the instance

        self.ButtonList.append(Button(frame, font=("Ariel", 16),width=10, height=10, fg="#ffffff", bg="#000000", text=buttonText)) #adding a button to your list of buttons
        self.lastButton=self.ButtonList[(len(self.ButtonList)-1)] #storing the last button to call grid outside the class

window=Tk()
anInstance=app(window)
anInstance.buttonLayout(anInstance.topFrame, "Cake")
anInstance.lastButton.grid(row=1,column=0)
window.mainloop()

同样,如果你做了按钮,你通常会在__init__中创建它们,但是你的应用程序有一个很好的按钮生成器,你甚至可以用它来创建一个框架生成器。你知道吗

由于self参数,您得到了错误。 还有一个问题是您的代码没有创建MyButtons类的实例。你知道吗

下面是一个从Button继承并自定义__init__以设置一些默认值的示例。你知道吗

import tkinter
import tkinter.messagebox

window = tkinter.Tk()    

#create default values for buttons
#frame and buttonText are the values passed to the class when making a new button

class MyButton(tkinter.Button):
    def __init__(self, *args, **kwargs):
        if not kwargs:
            kwargs = dict()
        kwargs['font'] = ("Arial", 16)
        kwargs['width'] = 10,
        kwargs['height'] = 10,
        kwargs['fg'] = '#ffffff',
        kwargs['bg'] = '#000000',
        super().__init__(*args, **kwargs)

topFrame = tkinter.Frame(window)
topFrame.pack()

#create new button here and place in the frame called topFrame with the text "Cake" on it
buttonCake = MyButton(topFrame, text="Cake")
#position the new button in a certain cell using grid in topFrame
buttonCake.grid(row=1, column=0)

window.mainloop()

这会将默认值强制输入到按钮中。只有在调用中不传递if语句时,才可以添加if语句来定义它们,方法如下:

if not 'width' in kwargs:
    kwargs['width'] = 10 

相关问题 更多 >