Python 将dataclass与Tkinter一起使用

Python 将dataclass与Tkinter一起使用,python,tkinter,Python,Tkinter,我试图权衡从tkinter小部件继承时使用dataclass的好处。问题是:我无法使用dataclass正确地继承tkinter按钮 下面是我通常从ttk按钮继承的方式(这非常有效) 我试图使同一类与dataclass工作的尝试如下(这给了我一个错误:builtins.TypeError:init()得到了一个意外的关键字参数“text”) 我的主要问题是:如何使上述数据类像第一个传统类一样工作?数据类有什么问题吗?我会尽力回答这个问题,尽管我对这个数据类功能还比较陌生。另外,请随意以任何方式纠

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

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

我试图使同一类与dataclass工作的尝试如下(这给了我一个错误:builtins.TypeError:init()得到了一个意外的关键字参数“text”)

我的主要问题是:如何使上述数据类像第一个传统类一样工作?数据类有什么问题吗?

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

您的数据类几乎没有问题

  • 错误消息本身就说明了这一点。由于数据类中没有字段
    text
    ,但即使添加字段
    text
    ,也会为传递给它的“root”参数引发相同的错误因此没有正确的字段。

  • 您没有将任何内容传递给按钮。您需要将参数传递给
    super()。\uuuu init\uuuu(…)
    ,将任何内容传递给
    super()。\uuuuu init\uuuu
    意味着传递给继承类的
    \uuu init\uuuu()
    。所以
    root
    text
    应该作为参数传递给
    super()

  • 此外,还需要将
    根字段
    文本字段
    设置为一个变量,以便将它们作为参数传递给
    \uuuuuuuuu post\uuuuu init\uuuu()方法。没有必要创建它们InitVar字段,它们可以像普通字段一样正常工作,但我认为应该这样做

  • 正确的例子:

    将tkinter作为tk导入
    从tkinter导入ttk
    从dataclasses导入dataclass,InitVar
    @数据类
    类自定义按钮(ttk.按钮):
    master:InitVar[tk.tk]
    文本:InitVar[str]
    新颜色:str
    按钮名称:str
    定义后初始化(自、主、文本):
    super()。\uuuuu init\uuuuu(master=master,text=text)
    self.s=ttk.Style(self)
    self.s.configure(f“{self.button_name}.TButton”,
    背景=自身。新颜色)
    self.configure(style=f“{self.button_name}.TButton”)
    如果uuuu name uuuuuu='\uuuuuuu main\uuuuuuu':
    root=tk.tk()
    button1=自定义按钮(
    root,text='Hello',button\u name=“warning\u button”,new\u color=“red”)
    按钮1.pack()
    root.mainloop()
    
    将类声明为
    数据类有什么意义?小部件显然不是数据类。这样做有什么好处?因为在创建
    CustomButton
    实例时传递了四个参数,所以需要在
    new\u color:str
    之前添加
    parent:any
    text:str
    。此外,您还需要将
    self.parent
    text=self.text
    参数传递给
    super()。\uuu init\uuu()
    @BryanOakley这正是我在这个实验中想要弄明白的——看看数据类在继承tkinter小部件时是否能从“传统”类中获益。但是我首先需要一种方法使数据类工作。我看不到任何额外的好处,坚持传统的方法,它也更传统。这太棒了。我不知道如果字段设置为InitVar,那么uuu post_init_uuuu()将获得传递的参数。这正是我需要的。
    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()
    
    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()