我有以下代码-
import tkinter as tk
from tkinter import ttk
from tkinter import messagebox
def main():
app = Application()
app.mainloop()
class Application(tk.Tk):
def __init__(self):
super().__init__()
self.title("Simple App")
self.geometry('800x500')
self.columnconfigure(0, weight=1)
# Blank space top left
frame1 = tk.Frame(self)
frame1.grid(row=0, column=0, columnspan=2)
# Frame containing the 4 buttons
frame2 = Buttons(self)
frame2.grid(row=0, column=2, sticky="nswe", padx=5, pady=5)
# Frame containing the first check boxes
frame3 = Checkbox(self)
frame3.grid(row=1, column=0, sticky="nswe", padx=5, pady=5)
# Frame for next check boxes
# frame4 = HandleCheckBox(self)
# frame4.grid(row=1, column=1, sticky="nswe", padx=5, pady=5)
class Buttons(ttk.Frame):
def __init__(self, parent):
super().__init__(parent)
self.entry_btn = ttk.Button(self, text="Add")
self.entry_btn.grid(row=0, column=0)
self.entry_btn2 = ttk.Button(self, text="Clear")
self.entry_btn2.grid(row=0, column=1)
self.entry_btn3 = ttk.Button(self, text="Continue")
self.entry_btn3.grid(row=0, column=2)
self.entry_btn4 = ttk.Button(self, text="Finish")
self.entry_btn4.grid(row=2, column=0, columnspan=3, sticky='nsew')
class Checkbox(ttk.Frame):
def __init__(self, parent):
super().__init__(parent)
self.checkbox_dict = {} # Stores INT VAR
self.second_checkbox_dict = {} # Stores INT VAR for second boxes
self.checkbox_list = [] # Stores WIDGET
self.destroy_second_checkbox = {} # Stores widgets for destruction
self.row = 0
self.second_row = 0
for key in dict1.keys():
self.checkbox_list.append(self.create_check_box(key))
def create_check_box(self, dict_key):
int_var = tk.IntVar(value=0) # Set initial value to 0 (unchecked)
checkbutton = ttk.Checkbutton(self, text=dict_key, variable=int_var,
command=lambda: self.check_state(dict_key))
checkbutton.grid(row=self.row, column=0, sticky='w')
self.checkbox_dict[dict_key] = int_var
self.row += 1
return checkbutton
def check_state(self, key):
state = self.checkbox_dict[key].get()
if state == 1:
self.destroy_second_checkbox[key] = []
for value in dict1[key]:
int_var = tk.IntVar(value=0) # Set initial value to 0 (unchecked)
checkbutton = ttk.Checkbutton(self, text=value, variable=int_var)
self.second_checkbox_dict[value] = int_var
checkbutton.grid(row=self.second_row, column=1, sticky='w')
self.destroy_second_checkbox[key].append(checkbutton)
self.second_row += 1
else:
for widget in self.destroy_second_checkbox[key]:
widget.destroy()
dict1 = {'item1': ['Lang1', 'Lang11'], 'item2': ['Lang2', 'Lang22'], 'item3': ['Lang3', 'Lang33']}
main()
产生这个窗口 -
当我选中标有“ITEM1, 2, 3”的框时,会弹出更多复选框,如下所示 -
但是,当取消选中 ITEM 框然后再次检查时,顺序不会保持不变,并且似乎忽略了 Row 变量,我知道 self.second_row 变量没有重置或更改。
我可以做些什么来确保当选中 ITEM 框时,相关值“LANG”被放置在特定区域而不是随机移动?
销毁复选框时需要更新
self.second_row
,并将剩余复选框重新放置在第 1 列。
以下是修改后的
check_state()
:
def check_state(self, key):
state = self.checkbox_dict[key].get()
if state == 1:
self.destroy_second_checkbox[key] = []
for value in dict1[key]:
int_var = tk.IntVar(value=0) # Set initial value to 0 (unchecked)
checkbutton = ttk.Checkbutton(self, text=value, variable=int_var)
self.second_checkbox_dict[value] = int_var
checkbutton.grid(row=self.second_row, column=1, sticky='w')
self.destroy_second_checkbox[key].append(checkbutton)
self.second_row += 1
else:
for widget in self.destroy_second_checkbox[key]:
widget.destroy()
self.second_row -= 1 # update self.second_row
# reposition existing checkboxes in column 1
# note that self.grid_slaves() returns widgets, most recently managed first
for row, cb in enumerate(self.grid_slaves(column=1)[::-1]):
cb.grid(row=row)