Python 为tkinter小部件创建一个类来调用默认属性
我正在尝试使用Python3中的tkinter创建GUI,它将有几个按钮,我不想每次都为所有按钮键入相同的属性,如下所示:Python 为tkinter小部件创建一个类来调用默认属性,python,class,user-interface,tkinter,widget,Python,Class,User Interface,Tkinter,Widget,我正在尝试使用Python3中的tkinter创建GUI,它将有几个按钮,我不想每次都为所有按钮键入相同的属性,如下所示: tkinter.Button(topFrame, font=("Ariel", 16), width=10, height=10, fg="#ffffff", bg="#000000", text="Cake") if not 'width' in kwargs: kwargs['width'] = 10 例如,每个按钮上的fg、
tkinter.Button(topFrame, font=("Ariel", 16), width=10, height=10,
fg="#ffffff", bg="#000000", text="Cake")
if not 'width' in kwargs:
kwargs['width'] = 10
例如,每个按钮上的fg
、bg
颜色和大小都相同。每个按钮上唯一改变的是文本以及在屏幕上放置它们的位置
我对编程和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()缺少1个必需的位置参数:“buttonText”
我很困惑,因为我正在传递“Cake”
,错误显示它丢失了
感谢您指出init我不知道如何使用init解决我的问题,但这和这里给出的答案都有所帮助。谢谢。由于self
参数,您会收到错误。
还有一个问题是,您的代码没有创建MyButtons
类的实例
下面的示例继承自按钮
,并自定义初始化
,以设置一些默认值
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
语句,以便仅当您不在调用中传递它们时,才定义它们,方法如下:
tkinter.Button(topFrame, font=("Ariel", 16), width=10, height=10,
fg="#ffffff", bg="#000000", text="Cake")
if not 'width' in kwargs:
kwargs['width'] = 10
因此,我对代码进行了注释,以便您可以了解一些东西
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()
此外,如果您使用按钮,您通常会在\uuuu init\uuuuu
中创建它们,但您的应用程序有一个很好的按钮生成器,您甚至可以用它创建一个框架生成器。您没有正确定义类和使用它。
以下是一个版本,其中包含使其正常工作所需的更正:
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()
更新
一种更为有效的方法是派生您自己的tkinter.Button
,这将允许它的实例由于继承而完全像基类的实例一样被使用-也就是说,无需记住在grid()
调用中引用它的newButton
属性,而不是按钮本身,这通常是需要的
下面所示的实现也非常灵活,因为在创建一个默认值时,只需通过常用的关联关键字参数为其提供不同的值,就可以轻松覆盖任何默认值
我在我的项目中使用了一个通用类,命名为Tools,其代码如下
def get_button(self, container, text, row=None, col=None):
w = ttk.Button(container, text=text, underline=0)
if row is not None:
w.grid(row=row, column=col, sticky=tk.W+tk.E, padx=5, pady=5)
else:
w.pack(fill =tk.X, padx=5, pady=5)
称为
self.tools = Tools()
f = ttk.Frame()
bts = [('Reset', self.on_reset),
('New', self.on_add),
('Edit', self.on_edit),
('Close', self.on_cancel)]
for btn in bts:
self.tools.get_button(f, btn[0] ).bind("<Button-1>", btn[1])
self.tools=tools()
f=ttk.Frame()
基站=[(“复位”,自复位),
(“新”,自我补充),
(“编辑”,自我编辑),
('Close',self.on_cancel)]
对于bts中的btn:
self.tools.get_按钮(f,btn[0]).bind(“,btn[1]”)
您可以轻松地扩展此add style属性。确切的错误意味着“self”参数没有传递给buttonLayout
函数,这在从对象调用实例方法时隐式发生。buttonLayout
应该是实例方法还是静态方法?它被定义为实例方法,但被称为静态方法。您应该创建一个myButton
类的实例,并从该实例调用buttonLayout
函数