You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何让for循环生成的ttk Combobox实现逐行独立联动更新值

实现每行品牌与车型下拉框独立联动的方案

问题根因

  • 循环创建控件时,反复将品牌、车型下拉框赋值给self的同名属性,循环结束后self.make_selection和self.model_selection只会保留最后一行的控件实例,更新操作自然只会作用在最后一行。
  • 事件绑定用到的lambda存在迟绑定特性,触发事件时取到的变量是循环结束后的最终值,永远指向最后一行的控件。

修正思路

不使用实例属性存储每行控件,通过lambda默认参数保存当前循环的车型下拉框实例,调整更新方法直接操作传入的当前行控件即可,保证每行的联动关系独立。

修正后完整可运行代码

import tkinter as tk
from tkinter import font as tkfont, filedialog, messagebox
from tkinter.ttk import Combobox

class SLS_v1(tk.Tk):
    def __init__(self, *args, **kwargs):
        tk.Tk.__init__(self, *args, **kwargs)
        # Setting up the root window
        self.title('Test App')
        self.geometry("200x300")
        self.resizable(False, False)
        self.title_font = tkfont.Font(family='Helvetica', size=18, weight="bold", slant="italic")
        container = tk.Frame(self)
        container.pack(side="top", fill="both", expand=True)
        container.grid_rowconfigure(0, weight=1)
        container.grid_columnconfigure(0, weight=1)
        self.frames = {}
        self.frames["MenuPage"] = MenuPage(parent=container, controller=self)
        self.frames["template"] = template(parent=container, controller=self)
        self.frames["MenuPage"].grid(row=0, column=0, sticky="nsew")
        self.frames["template"].grid(row=0, column=0, sticky="nsew")
        self.show_frame("MenuPage")
    def show_frame(self, page_name):
        frame = self.frames[page_name]
        frame.tkraise()

class MenuPage(tk.Frame):
    def __init__(self, parent, controller):
        tk.Frame.__init__(self, parent)
        self.controller = controller
        template = tk.Button(self, text='Template', height=3, width=20, bg='white', font=('12'),
                                command=lambda: controller.show_frame('template'))
        template.pack(pady=50)

class template(tk.Frame):
    def __init__(self, parent, controller):
        tk.Frame.__init__(self, parent)
        self.controller = controller
        self.grid(columnspan=10, rowspan=10)
        button = tk.Button(self, text='Click me', command= lambda: stored_functions().add_boxes(self))
        button.grid(row=11, column=1)

class stored_functions():
    make = ['Ford', 'Toyota', 'Honda']
    models = [['F-150', 'Mustang', 'Explorer'], ['Camry', 'Corolla', 'Tacoma'], ['Civic', 'CRV', 'Accord']]
    def add_boxes(self, main_window):
        for row in range(10):
            # 直接用局部变量存储当前行控件,不需要存入self
            make_selection = Combobox(main_window, value=self.make, state='readonly', width=10)
            make_selection.current(0)
            make_selection.grid(row=row, column=1)
            model_selection = Combobox(main_window, value=self.models[0], state='readonly', width=10)
            model_selection.current(0)
            model_selection.grid(row=row, column=2)
            # 用lambda默认参数保存当前行的车型下拉框实例,避免迟绑定问题
            make_selection.bind('<<ComboboxSelected>>', lambda event, m=model_selection: self.update_models(event.widget, m))
    def update_models(self, make_cb, model_cb):
        # 直接操作传入的当前行品牌、车型下拉框
        make_idx = self.make.index(make_cb.get())
        model_cb.config(values=self.models[make_idx])
        model_cb.current(0)

if __name__ == "__main__":
    app = SLS_v1()
    app.mainloop()

内容的提问来源于stack exchange,提问作者Lzypenguin

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.09.25 03:15:05