类继承多选

时间:2017-05-23 14:49:37

标签: python class inheritance tkinter

使用tkinter和我有两个完全相同的类(tk和toplevel)所以我合并了它们但需要选择我想要继承的窗口类型。

class Window(tk.Tk, tk.Toplevel):
    """ Basic root window (derived from tk.Tk) """
    def __init__(self, window, title = "None", geometry = ("300x150"),
                 resize = True, minMax = True, prompt = True):

        if window == "root":
            tk.Tk.__init__(self)
        elif window == "toplevel":
            tk.Toplevel.__init__(self)
        else:
            raise WindowTypeError("Incorrect window type '%s'" % window)

有没有更好的方法或更多的pythonic方法呢?

解决

import functools
import tkinter as tk
from tkinter import messagebox

# / import own modules
from exception_classes import WindowTypeError
# \ import own modules

class Window(object):
    def __init__(self,
                 window,
                 title    = "None",
                 geometry = ("300x150"),
                 resize   = True,
                 minMax   = True,
                 prompt   = True):


        if window == "root":
            self.window = tk.Tk()
        elif window == "toplevel":
            self.window = tk.Toplevel()
        else:
            raise WindowTypeError("Incorrect window type '%s'" % window)

        self.window.title(title)
        self.window.geometry(geometry)
        self.window.resizable(resize, resize)
        self.window.config(bg = "#ffffff")
        self.window.protocol("WM_DELETE_WINDOW", functools.partial(self.quit_window, prompt))
        self.window.attributes("-toolwindow", not minMax)
        self.raise_window()

    def quit_window(self, prompt = False):
        """ Confirmation for kill method """
        if prompt:
            if not messagebox.askyesno("Quit Application", "..."):
                return -1

        self.kill()

    def raise_window(self):
        self.window.attributes("-topmost", 1)
        self.window.attributes("-topmost", 0)

    def kill(self):
        """ Destroys the window """
        self.window.quit()
        self.window.destroy()


W = Window("root")

1 个答案:

答案 0 :(得分:3)

TkToplevel不是完全相同的类,您不应该继承这两个类。

如果您要创建主窗口,则您的类应继承自Tk。如果您要创建任何其他窗口,请继承Toplevel

如果您希望根窗口和其他窗口使用相同的代码,请将您的类作为Frame的子类,然后创建一个工厂,该工厂将创建包含以下内容的根或顶层窗口帧。

class MyApp(tk.Frame):
    def __init__(self, ...):
        ...
def create_window(window_type):
    if window_type == "root":
        root = tk.Tk()
        app = MyApp(root).pack(fill="both", expand=True)
    else:
        top = tk.Toplevel()
        app = MyApp(top).pack(fill="both", expand=True)
    return app

if __name__ == "__main__":
    create_window("root")

另一种策略是让你的应用程序都不继承,并使用composition:

class MyApp(object):
    def __init__(self, window, ...):
        if window == "root":
            self.root = tk.Tk()
        else:
            self.root = tk.Toplevel()
        ...