首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >在tk.Tk和tk.Toplevel中添加方法

在tk.Tk和tk.Toplevel中添加方法
EN

Stack Overflow用户
提问于 2019-11-01 19:08:56
回答 2查看 99关注 0票数 2

我想在tk.Tktk.Toplevel的实例中添加两个方法。前者以应用程序根窗口的形式存在,后者由用户创建多少次。每个tk.Toplevel代表应用程序的不同功能,目前存在13个变体。应用程序被配置为在任何时候只能创建每个变体的一个实例。

解决这一问题的一种方法可能是对这两个类进行子类划分:

代码语言:javascript
复制
class RootWindow(tk.Tk):
    def method_1(self):
        ...
    def method_2(self):
        ...

class TopWindow(tk.Toplevel):
    def method_1(self):
        ...
    def method_2(self):
        ...

由于我只希望为功能添加两个方法(这些方法与使用这些类的方法(如winfo_height())相同),子类看起来既多余又多余,因为相同的代码编写了两次。因此,另一种方法可能是使用setattr(),但我觉得这违反了类设计的开放/关闭原则:

代码语言:javascript
复制
def method_1(self):
    ...
def method_2(self):
    ...

class RootWindow(tk.Tk):
    def __init__(self):
        setattr(self, 'method_1', method_1)
        setattr(self, 'method_2', method_2)

class TopWindow(tk.Toplevel):
    def __init__(self):
        setattr(self, 'method_1', method_1)
        setattr(self, 'method_2', method_2)

现在,我只编写了一次方法,并修改了类;本质上,这凝聚了第一个方法,实际上是相同的。

考虑到tk.Tk是窗口,而tk.Toplevel是窗口,难道没有办法通过tkinter定义所有基于“窗口”的小部件都可以访问的方法吗?如果所有窗口都来自单个tkinter类,那么这不是一个问题,但是tk.Tk的根窗口与tk.Toplevel的根窗口不同(例如事件绑定,不一定是可视化行为)。

编辑:

查看@BryanOakley解决方案,我发现指针确实不喜欢这样;它们指向未解决的对属性的引用,我知道子类将访问这些属性,但不能访问混合类。请考虑以下几点:

代码语言:javascript
复制
class Mixin:
    def method(self):
        width = self.winfo_width()
        height = self.winfo_height()
        print(f'The window is {width} x {height}')

IDE指针抛出警告,因为self无法找到已定义的winfo_width。然而,我知道它将被来自tk.Tktk.Toplevel的子类的实例调用,但是滥用会导致未定义的行为,例如:

代码语言:javascript
复制
class OtherWindow(Window):
    pass

o = OtherWindow()
o.method()
# Attribute error

这有问题吗?提议的解决方案可以工作,但感觉它是被迫工作的,因为“我知道它将如何使用”。一个明显的解决方案是键入提示:

代码语言:javascript
复制
class Mixin:
    def method(self: Union[tk.Tk, tk.Toplevel]):
        width = self.winfo_width()
        height = self.winfo_height()
        print(f'The window is {width} x {height}')

因此,指针是令人满意的,代码对任何人都是可读的(假设它们不需要查找Union)。同样,当使用混合类(从未尝试过)时,这是否是预期的行为?

EN

回答 2

Stack Overflow用户

发布于 2019-11-01 19:22:33

我会用混音课。为TopWindowRootWindow保留自定义类是创建基本ToplevelTk类的专门化的正确解决方案,mixin解决了不想重复代码的问题。

例如:

代码语言:javascript
复制
class CustomMixin():
    def method_1(self):
        ...
    def method_2(self):
        ...

class TopWindow(CustomMixin, tk.Toplevel):
    pass

class RootWindow(CustomMixin, tk.Tk):
    pass
票数 2
EN

Stack Overflow用户

发布于 2019-11-01 19:22:24

编写一个拥有方法的类,然后在其他类中创建一个类属性,该类保留额外方法类的实例。

试试看,如果你有什么问题,请告诉我:

代码语言:javascript
复制
import tkinter as tk


class SomeExtraMethods:
    def __init__(self, window):
        self.window = window

    def size(self):
        return [self.window.winfo_width(), self.window.winfo_height()]


class RootWindow(tk.Tk):
    def __init__(self):
        super().__init__()
        self.extra = SomeExtraMethods(self)
        tk.Button(self, text='Print root window size', command=self.print_size).pack()
        tk.Button(self, text='Open top window', command=self.open_top).pack()

    def print_size(self):
        print(self.extra.size())

    def open_top(self):
        top = TopWindow()


class TopWindow(tk.Toplevel):
    def __init__(self):
        super().__init__()
        self.extra = SomeExtraMethods(self)
        tk.Button(self, text='Print top window size', command=self.print_size).pack()

    def print_size(self):
        print(self.extra.size())


if __name__ == '__main__':
    RootWindow().mainloop()

结果:

票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/58664587

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档