在 Tkinter 中重新定位复选框

问题描述 投票:0回答:1

我有以下代码-

    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()

产生这个窗口 -

enter image description here

当我选中标有“ITEM1, 2, 3”的框时,会弹出更多复选框,如下所示 -

enter image description here

但是,当取消选中 ITEM 框然后再次检查时,顺序不会保持不变,并且似乎忽略了 Row 变量,我知道 self.second_row 变量没有重置或更改。

我可以做些什么来确保当选中 ITEM 框时,相关值“LANG”被放置在特定区域而不是随机移动?

python-3.x tkinter
1个回答
0
投票

销毁复选框时需要更新

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)
© www.soinside.com 2019 - 2024. All rights reserved.