Python Tkinter-克隆根窗口属性并将其应用于顶级窗口

时间:2018-12-06 13:38:49

标签: python tkinter

我想创建多个外观几乎相同的窗口,而不必在每个函数中复制/粘贴所有窗口属性。

def child_window():
    childwindow.geometry("400x800")

def window_one():
    childwindow = Toplevel(root)
    childwindow.title("title window one")
    child_window()

def window_two():
    childwindow = Toplevel(root)
    childwindow.title("title window two")
    child_window()

该代码无效,因为子窗口不会从通用函数child_window中接管geometry属性。 有没有可能将设计复制到所有窗口的方法,而不必将整个代码放在每个函数中。

3 个答案:

答案 0 :(得分:1)

如果将Toplevel对象传递给child_window函数,则可以使用该对象直接设置该Toplevel窗口的几何形状(也请不要重复使用变量名) :

def child_window(window):
    window.geometry("400x800")

def window_one():
    childwindow = Toplevel(root)
    childwindow.title("title window one")
    child_window(childwindow)

def window_two():
    childwindow = Toplevel(root)
    childwindow.title("title window two")
    child_window(childwindow)

答案 1 :(得分:0)

您的代码不必要地重复自身,使DRY code principal失败,这是解决问题并遵循原则的解决方案。

from tkinter import *
from tkinter.ttk import *

def main():
    root = Tk()

    tops = list()
    for i in range(2):
        tops.append(same_top(root, 'title window ' + str(i)))

    mainloop()


def same_top(root, toptitle):
    child = Toplevel(root)
    child.title(toptitle)
    child.geometry("400x800")

    return child


if __name__ == '__main__':
    main()

您的问题是您的子函数不知道childwindow是谁,如果您将childwindow传递给几何函数,它将起作用。

您的固定代码:

from tkinter import *
from tkinter.ttk import *

def main():
    root = Tk()

    window_one(root)
    window_two(root)

    mainloop()


def child_window(childwindow):
    childwindow.geometry("400x800")

def window_one(root):
    childwindow = Toplevel(root)
    childwindow.title("title window one")
    child_window(childwindow)

def window_two(root):
    childwindow = Toplevel(root)
    childwindow.title("title window two")
    child_window(childwindow)


if __name__ == '__main__':
    main()

答案 2 :(得分:0)

我同意fhdrsdg的解决方案,但是我会改变一件事。 代替该函数仅持有一个单一的size设置值,而是让该函数先检查根窗口的大小,然后将相同的大小应用于顶级窗口。

您的主要问题可以通过几种方法解决。 一种方法是将顶级窗口传递给负责分配几何的函数。您还可以构建一个类(出于各种原因,IMO是最佳选择),还可以使用global来管理全局命名空间中的顶部窗口。

赞:

import tkinter as tk

def child_window(window):
    window.geometry("{}x{}".format(root.winfo_width(), root.winfo_height()))

def window_one():
    childwindow = tk.Toplevel(root)
    childwindow.title("title window one")
    child_window(childwindow)

def window_two():
    childwindow = tk.Toplevel(root)
    childwindow.title("title window two")
    child_window(childwindow)

root = tk.Tk()
root.geometry("500x300")
# I added this delay due to an issue tkinter has with reading the root size before the mainloop has had a change to fully load the root window.
root.after(1000, window_one)
root.after(1000, window_two)

root.mainloop()

有关OOP方法,请参见以下示例:

import tkinter as tk


class Example(tk.Tk):
    def __init__(self):
        tk.Tk.__init__(self)
        self.geometry("500x300")
        self.after(1000, self.window_one)
        self.after(1000, self.window_two)

    def child_window(self, window):
        print("{}x{}".format(self.winfo_width(), self.winfo_height()))
        window.geometry("{}x{}".format(self.winfo_width(), self.winfo_height()))

    def window_one(self):
        childwindow = tk.Toplevel(self)
        childwindow.title("title window one")
        self.child_window(childwindow)

    def window_two(self):
        childwindow = tk.Toplevel(self)
        childwindow.title("title window two")
        self.child_window(childwindow)

if __name__ == "__main__":
    Example().mainloop()