顶层 类 的新实例使小部件重叠
New instance of toplevel classes make overlapping widgets
我通常是 python 和 tkinter 的新手。我大概已经编程一年左右了,我刚刚开始尝试让每个 tkinter 顶级 window 成为自己的 class 因为我听说这是正确的方法.
我正在制作一个程序,其中有一个带有按钮的树视图,可以向其中添加内容。该按钮会打开一个新的 window,允许用户输入内容。我遇到的问题是当我必须实例化第一个 window 来更新树视图时,它似乎将第一个 window 上的所有小部件加倍。这导致它不断堆积,看起来很奇怪。
这是正常现象还是有更好的方法?
谢谢。如有必要,我可以 post 图片或我的代码。
编辑:缩短代码
from tkinter import *
from tkinter import ttk
class MainWindow:
Items = {'test': ['Material', '500']}
def __init__(self, master):
self.master = master
self.style = ttk.Style()
self.style.configure('TLabel', font=12)
ttk.Label(self.master, text="Items").grid(row=0, column=0, columnspan=3)
self.frmItems = ttk.Frame(self.master)
self.frmItems.grid(row=1, column=0, padx=5, pady=5, columnspan=3)
self.treeItems = ttk.Treeview(self.frmItems, columns=(0, 1, 2))
self.treeItems.column('#0', width=0, minwidth=0)
self.treeItems.column(1, width=80)
self.treeItems.column(2, width=80)
self.treeItems.heading(0, text="Name")
self.treeItems.heading(1, text="Type")
self.treeItems.heading(2, text="Price")
self.treeItems.grid(row=0, column=0)
self.itemscroll = ttk.Scrollbar(self.frmItems, command=self.treeItems.yview)
self.itemscroll.grid(row=0, column=1, sticky='ns')
self.treeItems.config(yscrollcommand=self.itemscroll.set)
ttk.Button(self.master, text="New", command=self.item_input_show).grid(row=2, column=0, padx=5, pady=5,
sticky='e')
ttk.Button(self.master, text="Edit").grid(row=2, column=1, padx=5, pady=5)
ttk.Button(self.master, text="Remove").grid(row=2, column=2, padx=5, pady=5, sticky='w')
def item_input_show(self):
ItemInput(self.master)
class ItemInput:
def __init__(self, master):
self.master = master
self.MainWindow = MainWindow(master)
self.topItemInput = Toplevel(self.master)
self.topItemInput.title("Input Item Properties")
def main():
root = Tk()
MainWindow(root)
root.mainloop()
if __name__ == "__main__":
main()
每次按下 New
按钮时,您都在呼叫 class MainWindow:
。这是一遍又一遍地重新制作所有小部件。他们创建 MainWindow 的方式会影响您与 MainWindow 交互的方式。
变化:
def main():
root = Tk()
MainWindow(root)
root.mainloop()
if __name__ == "__main__":
main()
收件人:
if __name__ == "__main__":
root = Tk()
main = MainWindow(root)
root.mainloop()
完成此更改后,您就可以与 main
的实例属性和方法进行交互
以下是您的代码的修改版本。您会注意到,当您按下我添加到 TopLevel window 的按钮时,它将打印来自 main
变量的属性和方法的信息。它还会在主窗口的输入框中放置一些文本。
from tkinter import *
from tkinter import ttk
class MainWindow:
def __init__(self, master):
self.master = master
self.btn = ttk.Button(self.master, text="New", command=self.item_input_show)
self.btn.pack(side = TOP)
self.entry = Entry(self.master)
self.entry.pack(side = BOTTOM)
self.numbers = 200
def two_plus_x(self, x):
math = 2 + x
return math
def item_input_show(self):
ItemInput(self.master)
class ItemInput:
def __init__(self, master):
self.master = master
self.topItemInput = Toplevel(master)
self.btn = ttk.Button(self.topItemInput, text="Use method in MainWindow", command = self.do_something_from_main)
self.btn.pack()
def do_something_from_main(self):
print(main.numbers)
print(main.two_plus_x(10))
main.entry.delete(0, END)
main.entry.insert(0, "From ItemInput Class")
# notice I removed def main(): as it was preventing us from interacting with the main variable.
if __name__ == "__main__":
root = Tk()
main = MainWindow(root)
root.mainloop()
我通常是 python 和 tkinter 的新手。我大概已经编程一年左右了,我刚刚开始尝试让每个 tkinter 顶级 window 成为自己的 class 因为我听说这是正确的方法.
我正在制作一个程序,其中有一个带有按钮的树视图,可以向其中添加内容。该按钮会打开一个新的 window,允许用户输入内容。我遇到的问题是当我必须实例化第一个 window 来更新树视图时,它似乎将第一个 window 上的所有小部件加倍。这导致它不断堆积,看起来很奇怪。
这是正常现象还是有更好的方法?
谢谢。如有必要,我可以 post 图片或我的代码。
编辑:缩短代码
from tkinter import *
from tkinter import ttk
class MainWindow:
Items = {'test': ['Material', '500']}
def __init__(self, master):
self.master = master
self.style = ttk.Style()
self.style.configure('TLabel', font=12)
ttk.Label(self.master, text="Items").grid(row=0, column=0, columnspan=3)
self.frmItems = ttk.Frame(self.master)
self.frmItems.grid(row=1, column=0, padx=5, pady=5, columnspan=3)
self.treeItems = ttk.Treeview(self.frmItems, columns=(0, 1, 2))
self.treeItems.column('#0', width=0, minwidth=0)
self.treeItems.column(1, width=80)
self.treeItems.column(2, width=80)
self.treeItems.heading(0, text="Name")
self.treeItems.heading(1, text="Type")
self.treeItems.heading(2, text="Price")
self.treeItems.grid(row=0, column=0)
self.itemscroll = ttk.Scrollbar(self.frmItems, command=self.treeItems.yview)
self.itemscroll.grid(row=0, column=1, sticky='ns')
self.treeItems.config(yscrollcommand=self.itemscroll.set)
ttk.Button(self.master, text="New", command=self.item_input_show).grid(row=2, column=0, padx=5, pady=5,
sticky='e')
ttk.Button(self.master, text="Edit").grid(row=2, column=1, padx=5, pady=5)
ttk.Button(self.master, text="Remove").grid(row=2, column=2, padx=5, pady=5, sticky='w')
def item_input_show(self):
ItemInput(self.master)
class ItemInput:
def __init__(self, master):
self.master = master
self.MainWindow = MainWindow(master)
self.topItemInput = Toplevel(self.master)
self.topItemInput.title("Input Item Properties")
def main():
root = Tk()
MainWindow(root)
root.mainloop()
if __name__ == "__main__":
main()
每次按下 New
按钮时,您都在呼叫 class MainWindow:
。这是一遍又一遍地重新制作所有小部件。他们创建 MainWindow 的方式会影响您与 MainWindow 交互的方式。
变化:
def main():
root = Tk()
MainWindow(root)
root.mainloop()
if __name__ == "__main__":
main()
收件人:
if __name__ == "__main__":
root = Tk()
main = MainWindow(root)
root.mainloop()
完成此更改后,您就可以与 main
以下是您的代码的修改版本。您会注意到,当您按下我添加到 TopLevel window 的按钮时,它将打印来自 main
变量的属性和方法的信息。它还会在主窗口的输入框中放置一些文本。
from tkinter import *
from tkinter import ttk
class MainWindow:
def __init__(self, master):
self.master = master
self.btn = ttk.Button(self.master, text="New", command=self.item_input_show)
self.btn.pack(side = TOP)
self.entry = Entry(self.master)
self.entry.pack(side = BOTTOM)
self.numbers = 200
def two_plus_x(self, x):
math = 2 + x
return math
def item_input_show(self):
ItemInput(self.master)
class ItemInput:
def __init__(self, master):
self.master = master
self.topItemInput = Toplevel(master)
self.btn = ttk.Button(self.topItemInput, text="Use method in MainWindow", command = self.do_something_from_main)
self.btn.pack()
def do_something_from_main(self):
print(main.numbers)
print(main.two_plus_x(10))
main.entry.delete(0, END)
main.entry.insert(0, "From ItemInput Class")
# notice I removed def main(): as it was preventing us from interacting with the main variable.
if __name__ == "__main__":
root = Tk()
main = MainWindow(root)
root.mainloop()