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

tkinter循环创建Radiobutton时command函数仅最后一个生效问题咨询

问题根因

你在循环调用pins()方法时,所有控件和变量都绑定到了MSM类的同一个实例属性上(比如self.var_wiretype、self.R1_discipline),每一轮循环都会覆盖上一轮的属性值,最终实例里只保留最后一个port对应的控件和变量,所以点击任意frame的单选按钮,操作的都是最后一组属性。

解决方案

将每个port对应的frame、控件、变量、回调逻辑封装为独立的子类,每个port对应一个子类实例,各自维护自身的属性,避免互相覆盖。

修改后完整代码

import tkinter as tk
from tkinter import ttk, Frame, BOTH, LEFT, Canvas, IntVar, Radiobutton

# 新增PortFrame子类,每个port对应一个独立实例
class PortFrame(tk.Frame):
    def __init__(self, parent, port, *args, **kwargs):
        super().__init__(parent, *args, **kwargs)
        self.pack(fill='both', expand=1)
        # 每个port实例自己维护变量和控件,不会互相覆盖
        self.var_wiretype = IntVar()
        self.R1_wiretype = Radiobutton(self, text=("wire", port), variable=self.var_wiretype, value=1, command=self.sel_wiretype_1)
        self.R1_wiretype.grid(row=1, column=1, sticky='W')
        self.R2_wiretype = Radiobutton(self, text=("wreal", port), variable=self.var_wiretype, value=2, command=self.sel_wiretype_1)
        self.R2_wiretype.grid(row=1, column=2, sticky='W')

        self.var_discipline = IntVar()
        self.R1_discipline = Radiobutton(self, text="logic", variable=self.var_discipline, value=1)
        self.R1_discipline.grid(row=2, column=1, sticky='W')
        self.R2_discipline = Radiobutton(self, text="vreal", variable=self.var_discipline, value=2)
        self.R2_discipline.grid(row=2, column=2, sticky='W')
        self.R3_discipline = Radiobutton(self, text="ireal", variable=self.var_discipline, value=3)
        self.R3_discipline.grid(row=2, column=3, sticky='W')
        self.R4_discipline = Radiobutton(self, text="other", variable=self.var_discipline, value=4)
        self.entry1 = ttk.Entry(self, width=10)
        self.entry1.grid(row=3, column=2)
        self.R4_discipline.grid(row=3, column=1, sticky='W')

    def sel_wiretype_1(self):
        # 回调只操作当前实例自身的控件,不会影响其他port
        if self.var_wiretype.get() == 1:
            self.R1_discipline['state'] = 'active'
            self.R2_discipline['state'] = 'disabled'
            self.R3_discipline['state'] = 'disabled'
            self.var_discipline.set(1)
        else:
            self.R1_discipline['state'] = 'disabled'
            self.R2_discipline['state'] = 'active'
            self.R3_discipline['state'] = 'active'
            self.var_discipline.set(2)

class MSM:
    def __init__(self, top):
        self.top = top
        # 创建主框架
        self.main_frame = Frame(self.top, width=50, height=100, bd=1)
        self.main_frame.pack(fill=BOTH, expand=1)

        # 创建画布
        self.my_canvas = Canvas(self.main_frame)
        self.my_canvas.pack_propagate(0)
        self.my_canvas.pack(side=LEFT, fill=BOTH, expand=1)
        self.second_frame = Frame(self.my_canvas)
        self.second_frame.pack(fill=BOTH, expand=1) # 修复原代码未pack的问题

        port_str = ['port1', 'port2', 'port3', 'port4', 'port5'] # 替换为你实际的port值
        # 每个port创建独立的PortFrame实例
        for port in port_str:
            PortFrame(self.second_frame, port)

if __name__ == "__main__":
    root = tk.Tk()
    app = MSM(root)
    root.mainloop()

关键修改说明

  • 新增PortFrame子类封装单port的所有逻辑,实例属性互不覆盖
  • 修复原代码中second_frame未pack、frame_portdetails_top未定义的错误
  • 回调方法现在只操作当前实例自身的控件,不会串到其他port的组件

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.10.04 17:45:04