[英]Create a class for tkinter widgets to call default attributes
我正在嘗試使用 Python3 中的 tkinter 創建一個 GUI,它將有幾個按鈕,我不想每次都為它們鍵入相同的屬性,如下所示:
tkinter.Button(topFrame, font=("Ariel", 16), width=10, height=10,
fg="#ffffff", bg="#000000", text="Cake")
例如,每個按鈕上的fg
、 bg
顏色和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解決我的問題,但這和這里給出的答案有所幫助。 謝謝你。
由於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 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()
另外,如果你做按鈕,你通常在__init__
創建它們,但你的應用程序有一個很好的按鈕構建器,你甚至可以用它制作一個框架構建器。
你沒有定義你的類並正確使用它。
這是一個版本,其中包含使其工作所需的更正:
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
子類,這將允許它的實例與基類的實例完全一樣使用,因為繼承 - 即這樣就不需要記住引用它的newButton
grid()
調用中的屬性而不是按鈕本身,這通常是必需的。
下面顯示的實現也非常靈活,因為您可以在創建默認值時輕松覆蓋任何默認值,只需通過通常的關聯關鍵字參數為其提供不同的值。
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()
我在我的項目中使用了一個通用類,名為 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])
您可以輕松擴展此添加樣式屬性。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.