如何解决通过类创建的按钮未在tkinter GUI中正确打包
在我的项目中,具有相同文本,颜色,字体大小等的按钮被多次使用。因此,我为此创建了一个按钮类,这样我就不必一次又一次地给出上述参数。但是问题是,按钮没有打包在我分配的主目录/根目录/框架中,而是打包在主根窗口中。 这是一个简单的代码,其中按钮未包装在标签框架内。
{{1}}
解决方法
您将在此代码行中将master
设置为None
:
Button.__init__(self,master = None,...)
您需要传入调用者给定的master
值:
Button.__init__(self,master,...)
,
您的问题已得到正确答案,但这是您未曾提出但肯定需要知道的问题的答案。您正在创建一个容纳Button
的类,但是您的类没有向Button
添加任何内容。似乎让您上课的唯一原因是“内部”分配所有options
并使其本身pack
。但是,即使您正在重复自己。所有这些您甚至都没有将command
传递给按钮,因此您真正拥有的是经过过度设计的Button
,它什么也没做。
更好的解决方案是事先准备kwargs
,然后使用它们。做到这一点的一种方法是通过dataclasses
,如下所示。这样,您就可以为Buttons
创建默认的“样式”,并在需要其他稍有不同的按钮时仅覆盖要更改的部分。确定要放入dataclass
的内容非常简单。找到您想要为其制作dataclass
的任何小部件的文档,然后列出所有被视为option
的东西。您只想从不断变化的options
中排除dataclass
(例如command
和text
),然后手动输入这些自变量〜,如下所示。
import tkinter as tk
from dataclasses import dataclass,asdict
@dataclass
class Button_dc:
activeforeground: str = 'black'
activebackground: str = 'white'
foreground: str = 'white'
background: str = 'black'
highlightcolor: str = 'red'
relief: str = 'flat'
justify: str = 'center'
font: str = 'Calibri 14 bold'
compound: str = 'left'
state: str = 'normal'
underline: int = -1
wraplength: int = -1
padx: int = 2
pady: int = 2
border: int = 2
width: int = 0
height: int = 0
DefaultButton = asdict(Button_dc()) #default
SpecialButton = asdict(Button_dc(padx=60,pady=60,font='Helvetica 12')) #noticeably different
class App(tk.Tk):
WIDTH = 800
HEIGHT = 600
TITLE = 'Example'
def __init__(self,**kwargs):
tk.Tk.__init__(self,**kwargs)
#this is emphatically more tidy than creating a custom widget class every time you want to style a widget
tk.Button(self,text='view',command=self.view,**DefaultButton).grid(column=0)
tk.Button(self,text='click',command=self.click,**SpecialButton).grid(column=0)
def view(self):
print('I have been viewed')
def click(self):
print('I have been clicked')
if __name__ == '__main__':
app = App()
app.title(App.TITLE)
app.geometry(f'{App.WIDTH}x{App.HEIGHT}')
app.resizable(width=False,height=False)
app.mainloop()
如果您确实需要扩展widget
,您仍然可以使用此方法有效地设置选项〜,如下所示:
class ComplexButton(tk.Button):
def __init__(self,text,command,**kwargs):
#this will still default to everything in Button_dc that is not explicitly set in kwargs
self.default = asdict(Button_dc(**kwargs))
tk.Button.__init__(self,text=text,command=command,**self.default)
self.hover = self.default.copy()
self.hover['background'] = 'red'
self.bind("<Enter>",self.on_enter)
self.bind("<Leave>",self.on_leave)
def on_enter(self,event):
self.configure(**self.hover)
def on_leave(self,event):
self.configure(**self.default)