ttk组合框选择同步进入状态

ttk combobox selection synchronize the state of entry

我想实现一个特例,当我selectcombobox中的值时,entry状态会相应改变,例如当我 select 1 级别时,级别 1 的条目处于活动状态,而级别 2 的条目被禁用,任何人都可以给我一些建议。当我select 2个关卡时,两个进入状态都开启

# -*- coding: utf-8 -*-
import tkinter as tk
from tkinter import ttk



class MainGui(tk.Tk):

    def __init__(self):

        super().__init__()
        self.create_widgets()

    def create_widgets(self):

        label_1 = tk.Label(self,
                  text = "Levels:",
                  anchor = 'w')
        label_1.grid(row=0, column=0)

        ComboBox1 = ttk.Combobox(self, width = 10, state = 'readonly')
        ComboBox1["values"] = ("1", "2")
        ComboBox1.current(0)
        ComboBox1.grid(row=0, column=1)

        label1 = tk.Label(self,
                  text = "Level-1:",
                  anchor = 'w')
        label1.grid(row=1, column=0)

        entry1 = tk.Entry(self,
                      width = 10,
                      )
        entry1.grid(row=1, column=1)

        label2 = tk.Label(self,
                  text = "Level-2:",
                  anchor = 'w')
        label2.grid(row=2, column=0)

        entry2 = tk.Entry(self,
                      width = 10,
                      )
        entry2.grid(row=2, column=1)


def main():

    # gui
    root = MainGui()
    root.mainloop()


if __name__ == '__main__':
    main()

您可以在 ComboBox1 上绑定虚拟事件 <<ComboboxSelected>> 并在事件回调中更新 Entry2 的状态,只要选择 ComboBox1 就会执行变了。但是您需要将 ComboBox1entry2 更改为实例变量,以便在事件回调中访问它们:

def create_widgets(self):
    ...
    # changed ComboBox1 to instance variable self.ComboBox1
    self.ComboBox1 = ttk.Combobox(self, width = 10, state = 'readonly')
    self.ComboBox1["values"] = ("1", "2")
    self.ComboBox1.current(0)
    self.ComboBox1.grid(row=0, column=1)
    self.ComboBox1.bind("<<ComboboxSelected>>", self.on_select)
    ...
    # changed entry2 to instance variable self.entry2
    self.entry2 = tk.Entry(self,
                          width = 10,
                          state = "disabled"  # initially disabled
                          )
    self.entry2.grid(row=2, column=1)

def on_select(self, event=None):
    # set state of entry2 based on selected value
    self.entry2.config(state="normal" if self.ComboBox1.get()=="2" else "disabled")

这是一个解决方案(示例):

from tkinter import Tk, Label, Entry, Frame
from tkinter.ttk import Combobox


entry_list = []


def activate_entries(event=None):
    to = int(combobox.get())
    for entry in entry_list[:to]:
        entry.config(state='normal')
    for entry in entry_list[to:]:
        entry.config(state='disabled')


root = Tk()

values = []
for i in range(5):
    (frame := Frame(root)).grid(row=i + 1, column=0)
    Label(frame, text=f'Level-{i + 1}').pack()
    (e := Entry(frame, state='disabled' if i != 0 else 'normal',
                disabledbackground='grey80')).pack()
    entry_list.append(e)
    values.append(i + 1)

combobox = Combobox(root, values=values, state='readonly')
combobox.current(0)
combobox.grid(row=0, column=0)

combobox.bind('<<ComboboxSelected>>', activate_entries)

root.mainloop()

这里的主要部分是 activate_entries() 函数,它只是从组合框获取值,并使用条目列表根据组合框给出的列表中的索引设置它们的状态。 (还有一些部分需要 Python 3.8 或更高版本,也可以针对旧版本进行调整),还要注意当用户从组合框。

编辑:添加了 disabledbackground='grey80' 以直观地指示该条目已被禁用

EDIT2:您显然可以将范围设置为两个,这将创建两个条目,它们的引用保存在 entry_list 中,因此您可以通过该列表访问它们以获取它们的值,例如