我有一个名为view的按钮,当单击它时,将创建一个新窗口,其中包含一个列表框中的列表以及与该列表框相对应的复选框列表。切换列表框中的项目时,您会看到列表框中的项目彼此独立,并且具有自己的复选框值。截至目前,它会记住每个列表框项目的复选框值,除非您关闭创建的窗口。当您关闭创建的第二个窗口时,尝试再次打开该窗口时,所有这些信息都会消失。我需要一种方法来创建第二个窗口,使用列表框和复选框来完成它现在要做的所有事情,但是当关闭窗口时,可以再次打开它并从上次退出的地方继续。
例如,如果我突出显示列表框中的第一项并选中第一个复选框,那么我应该能够关闭该窗口并再次打开它,并且当突出显示列表框中的第一项时,我看到有一个选中第一个复选框。
import tkinter
from tkinter import *
def myfunction(event):
canvas1.configure(scrollregion=canvas1.bbox("all"))
def onselect(evt):
# Note here that Tkinter passes an event object to onselect()
w = evt.widget
x = 0
index = int(w.curselection()[0])
value = w.get(index)
print('You selected item %d: "%s"' % (index, value))
for y in enable:
for item in list_for_listbox:
checkbuttons[item][y][1].grid_forget()
checkbuttons[value][y][1].grid(row=x, column=0)
# Label(frame2, text="some text").grid(row=x, column=1)
x += 1
def printcommand():
for item in list_for_listbox:
for y in enable:
print(item + " [" + y + "] " + str(checkbuttons[item][y][0].get()))
def create_new_window():
global new_window
new_window = tkinter.Toplevel()
new_window.geometry("750x500")
new_window_commands()
master = tkinter.Tk()
master.title("Checkboxes test")
master.geometry("750x500")
button1 = Button(master, command =create_new_window,text="View")
button1.place(x=50,y=250)
def new_window_commands():
# enable = ['button 1', 'button 2', 'button 3', 'button 4', 'button 5', 'button 6', 'button 7']
global list_for_listbox
global enable
global checkbuttons
global canvas1
enable = []
for x_number_of_items in range(1, 15):
enable.append("button " + str(x_number_of_items))
list_for_listbox = ["one", "two", "three", "four"]
listbox = Listbox(new_window)
listbox.place(x=5, y=5, width=100, height=10 + 16*len(list_for_listbox))
listbox.update()
frame1 = Frame(new_window, borderwidth=1, relief=GROOVE, highlightthickness=1, highlightbackground="black",
highlightcolor="black")
frame1.place(x=listbox.winfo_width() + 10, y=5, width=300, height=listbox.winfo_height())
canvas1 = Canvas(frame1)
frame2 = Frame(canvas1, height=500)
scrollbar1 = Scrollbar(frame1, orient="vertical", command=canvas1.yview)
canvas1.configure(yscrollcomman=scrollbar1.set)
scrollbar1.pack(side="right", fill="y")
canvas1.pack(side="left")
canvas1.create_window((0, 0), window=frame2, anchor='nw')
frame2.bind("<Configure>", myfunction)
printbutton = Button(new_window, text="Print", command=printcommand)
printbutton.place(x=100, y=250)
checkbuttons = {}
for item in list_for_listbox:
listbox.insert(END, item)
checkbuttons[item] = (dict())
for y in enable:
temp_var = BooleanVar()
checkbuttons[item][y] = [temp_var, Checkbutton(frame2, text=y, variable=temp_var)]
listbox.bind('<<ListboxSelect>>', onselect)
print(enable)
mainloop()
printcommand()
答案 0 :(得分:2)
使用当前结构,最简单的解决方法是:
new_window
。withdraw()
new_window
,而不是每次都关闭它。new_window
的相同实例。您需要实现以下内容:
# Default your new_window to None
new_window = None
def create_new_window():
global new_window
# If new_window doesn't exist, create a new one
if not new_window:
new_window = tkinter.Toplevel()
new_window.geometry("750x500")
# add a new protocol to redirect on closing the window.
new_window.protocol("WM_DELETE_WINDOW", hide_window)
new_window_commands()
else:
# if new_window already exist, just unhide it
new_window.deiconify()
# add a new function for when window is closing
def hide_window():
global new_window
new_window.withdraw()
您可能还想在protocol
下添加相同的master
方法,以便在关闭时销毁master
和new_window
对象:
master.protocol('WM_DELETE_WINDOW', destroy_all)
def destroy_all():
global master
global new_window
master.destroy()
new_window.destroy()
如果可能,我建议您在下一个tkinter代码中考虑使用object oriented approach。我稍后再看能否提供简短的示例。
作为旁注,尽管我了解tkinter
的许多文档都使用from tkinter import *
方法,但我不鼓励这种做法,建议改用import tkinter as tk
(或者您已经这样做了) ,import tkinter
,可以完成相同的操作)。 See relevant answer here
以下是类似的OOP方法的快速示例:
import tkinter as tk
# Here the main window can be called upon as its own instance with its own instance attributes.
class Window(tk.Tk):
def __init__(self):
super().__init__()
self.main_button = tk.Button(self, text="Creat a sub window", command=self.open_sub_window)
self.main_button.pack()
# define the things you wish to retain under the main window as an instance attribute
self.sub_check_var = tk.BooleanVar()
self.sub_entry_var = tk.StringVar()
# when creating a new window, just reference back to the main attributes you've already created.
def open_sub_window(self):
self.sub_window = tk.Toplevel()
tk.Checkbutton(self.sub_window, text="I'm a checkbox!", variable=self.sub_check_var).pack()
lbl_frm = tk.LabelFrame(self.sub_window, text="I am an entry!")
lbl_frm.pack()
tk.Entry(lbl_frm, text=self.sub_entry_var).pack()
gui = Window()
gui.mainloop()
请注意,这只是一种方法。您只需要四处摸索以熟悉自己的实现,就没有做对/错做事的方式。