将dataclass与Tkinter一起使用



我试图权衡从tkinter小部件继承时使用数据类的好处。问题是:我无法使用数据类正确地继承tkinter按钮。

以下是我通常从ttk按钮继承的方式(这非常有效(。

import tkinter as tk
from tkinter import ttk    

class CustomButton(ttk.Button):
def __init__(self, master, button_name, new_colour, **kw):
super().__init__(master, **kw)

self.new_colour = new_colour
self.button_name = button_name

self.s = ttk.Style(self)
self.s.configure(f"{button_name}.TButton", background=new_colour)

self.configure(style=f"{button_name}.TButton")

root = tk.Tk()
button1 = CustomButton(root, text="OK", button_name="warning_button", new_colour="red")
button1.pack()
root.mainloop()

我尝试让同一个类作为数据类工作如下(这给了我错误:builtins.TypeError:init((得到了一个意外的关键字参数'text'(

import tkinter as tk
from tkinter import ttk    
from dataclasses import dataclass

@dataclass
class CustomButton(ttk.Button):

new_colour: str
button_name: str
def __post_init__(self):
super().__init__()

self.s = ttk.Style(self)
self.s.configure(f"{self.button_name}.TButton", background=self.new_colour)

self.configure(style=f"{self.button_name}.TButton")

root = tk.Tk()
button1 = CustomButton(root, text="OK", button_name="warning_button", new_colour="red")
button1.pack()
root.mainloop()

我的主要问题是:如何使上面的数据类像第一个传统类一样工作?我在数据类上做错了什么?

尽管我对这个数据类功能还很陌生,但我会尽力回答这个问题。此外,请随时以任何方式纠正我

您的数据类几乎没有问题。

  1. 错误消息不言自明。由于您的数据类中没有字段text,但即使您添加字段text,它也会为";根";参数传递给它。所以右边的字段不在那里

  2. 您没有向按钮传递任何信息您需要向super().__init__(...)传递参数,向super().__init__传递任何参数都意味着传递给继承类的__init__()。因此roottext应该作为参数传递给super().__init__()

  3. 此外,还需要将roottext字段设置为InitVar字段,以便将它们作为参数传递给__post__init__()方法。没有必要创建它们InitVar字段,它们可以像普通字段一样正常工作,但我认为应该这样做。

正确示例:

import tkinter as tk
from tkinter import ttk
from dataclasses import dataclass, InitVar

@dataclass
class CustomButton(ttk.Button):
master: InitVar[tk.Tk]
text: InitVar[str]
new_colour: str
button_name: str
def __post_init__(self, master, text):
super().__init__(master=master, text=text)
self.s = ttk.Style(self)
self.s.configure(f"{self.button_name}.TButton",
background=self.new_colour)
self.configure(style=f"{self.button_name}.TButton")

if __name__ == '__main__':
root = tk.Tk()
button1 = CustomButton(
root, text='Hello', button_name="warning_button", new_colour="red")
button1.pack()
root.mainloop()

最新更新