簡體   English   中英

為 tkinter 小部件創建一個類以調用默認屬性

[英]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")

例如,每個按鈕上的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解決我的問題,但這和這里給出的答案有所幫助。 謝謝你。

由於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.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM