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

Tkinter中使用tk.IntVar获取Checkbox状态返回地址而非值及Save按钮存储状态到字典失败的问题咨询

Fixing Your Tkinter Checkbox and Dictionary Issues

Let's tackle your two problems one by one, with clear explanations and actionable fixes:

1. Getting Variable Address Instead of Checkbox State

The root issue here is that your self.colors dictionary (and later self.comp_add_drop_status) stores tk.IntVar objects, not their actual integer state values. When you print or access these entries directly, you're seeing the object's memory address instead of the 0/unchecked or 1/checked status.

To get the real state, you need to call the .get() method on each IntVar instance. For example, instead of self.comp_add_drop_status["f1_Blue"], use self.comp_add_drop_status["f1_Blue"].get().

2. Saving Checked States to a New Dictionary

Your current save_colors2dict method was fetching the IntVar objects but not retrieving their values, and it lacked the logic to filter checked items. Here's how to fix this:

Modified save_colors2dict Method

def save_colors2dict(self):
    # Initialize empty dictionary for checked items
    selected_colors = {}
    
    # Iterate over each color and its associated IntVar
    for color_name, var in self.comp_add_drop_status.items():
        # Get the actual checkbox state (0 or 1)
        current_state = var.get()
        if current_state == 1:
            # Add to new dictionary if the checkbox is checked
            selected_colors[color_name] = current_state
    
    # Print results to verify functionality
    print("All IntVar objects:", self.comp_add_drop_status.values())
    print("Checked colors:", selected_colors)
    
    # Return the selected colors for further use
    return selected_colors

Key Fixes Explained

  • We loop through all key-value pairs in the status dictionary
  • For each entry, we call .get() on the IntVar to get its current state
  • We only add entries where the state is 1 (checked) to the new dictionary

Full Modified Code

Here's your complete code with fixes applied, plus minor cleanups for consistency:

import tkinter as tk
from tkinter import ttk

class ToolTip(object):
    def __init__(self, widget):
        self.widget = widget
        self.tip_window = None

    def show_tip(self, tip_text):
        """Display text in a tooltip window"""
        if self.tip_window or not tip_text:
            return
        x, y, _cx, cy = self.widget.bbox("insert") # get size of widget
        x = x + self.widget.winfo_rootx() + 25 # calculate to display tooltip
        y = y + cy + self.widget.winfo_rooty() + 25 # below and to the right
        self.tip_window = tw = tk.Toplevel(self.widget) # create new tooltip window
        tw.wm_overrideredirect(True) # remove all Window Manager (wm) decorations
        tw.wm_geometry("+%d+%d" % (x, y)) # create window size
        label = tk.Label(tw, text=tip_text, justify=tk.LEFT, background="#ffffe0", relief=tk.SOLID, borderwidth=1, font=("tahoma", "8", "normal"))
        label.pack(ipadx=1)

    def hide_tip(self):
        tw = self.tip_window
        self.tip_window = None
        if tw:
            tw.destroy()

def create_ToolTip(widget, text):
    toolTip = ToolTip(widget) # create instance of class
    def enter(event):
        toolTip.show_tip(text)
    def leave(event):
        toolTip.hide_tip()
    widget.bind('<Enter>', enter) # bind mouse events
    widget.bind('<Leave>', leave)

class OOP(tk.Frame):
    def __init__(self, parent):
        # Initializer method
        tk.Frame.__init__(self, parent)
        self.canvas = tk.Canvas(self, borderwidth=0, background="#ffffff")
        self.frame = tk.Frame(self.canvas, background="#ffffff")
        self.vsb = tk.Scrollbar(self, orient="vertical", command=self.canvas.yview)
        self.canvas.configure(yscrollcommand=self.vsb.set)
        self.hsb = tk.Scrollbar(self, orient="horizontal", command=self.canvas.xview)
        self.canvas.configure(xscrollcommand=self.hsb.set)

        self.vsb.pack(side="right", fill="y")
        self.hsb.pack(side="bottom", fill="x")
        self.canvas.pack(side="left", fill="both", expand=True)
        self.canvas_window = self.canvas.create_window((4,4), window=self.frame, anchor="nw", tags="self.frame")

        self.frame.bind("<Configure>", self.onFrameConfigure)#Bind an event whenever the size of the frame changes
        self.canvas.bind("<Configure>", self.onCanvasConfigure)#Enables scrolling

        self.colors = {"f1_Blue": 0, "f2_Red": 0, "f3_Green": 0, "f4_Black": 0, "f5_White": 0, "f6_Purple": 0}
        self.tabControl = ttk.Notebook(self.frame, width=2500, height=1100) # Create Tab Control
        self.tab_menu = ttk.Frame(self.tabControl) # Create a tab
        self.tab_menu.pack(fill=tk.BOTH, expand=1)
        self.tabControl.add(self.tab_menu, text="MENU") # Add a MENU tab
        self.tabControl.pack(expand=1, fill="both") # Pack to make visible

        self.label1 = tk.Label(self.tab_menu, text=' Status ', fg='white', bg='black')
        self.mighty = ttk.LabelFrame(self.tab_menu, labelwidget=self.label1)
        self.mighty.grid(column=0, row=0, padx=20, pady=10)

        self.comp_add_drop_status = self.check_box_addordrop(1, 0, self.mighty, self.colors)

        ttk.Label(self.mighty, text="Save the colors?", foreground="blue").grid(column=0, row=15, sticky=tk.W, columnspan=3)
        self.action = ttk.Button(self.mighty, text="Save", command=self.save_colors2dict)
        self.action.grid(column=5, row=15, sticky=tk.E, columnspan=3)

        # Add a title
        parent.title("TESTER")
        parent.resizable(1, 1)

    def onFrameConfigure(self, event):
        self.canvas.configure(scrollregion=self.canvas.bbox("all")) #Reset the scroll region to encompass the inner frame

    def onCanvasConfigure(self, event):
        canvas_width = event.width
        self.canvas.itemconfig(self.canvas_window, width=canvas_width) #Whenever the size of the canvas changes, alter the the window region respectively

    def check_box_addordrop(self, r, c, frame, items):
        cow = c
        row = r
        self.my_list_test = []
        for item in items:
            items[item] = tk.IntVar(value=items[item])
            checkbox = tk.Checkbutton(frame, text=item[3:15], variable=items[item])
            checkbox.grid(column=cow, row=row, sticky=tk.W)
            row += 1
        return items

    def save_colors2dict(self):
        selected_colors = {}
        for color_name, var in self.comp_add_drop_status.items():
            if var.get() == 1:
                selected_colors[color_name] = 1
        
        print("All checkbox variables:", self.comp_add_drop_status.values())
        print("Selected colors:", selected_colors)
        return selected_colors

if __name__ == '__main__':
    win = tk.Tk()
    example = OOP(win)
    example.pack(fill="both", expand=True)
    win.mainloop()

Additional Cleanups

  • Removed redundant from tkinter import * import to avoid namespace clutter
  • Changed win.title() to parent.title() in the class initializer (uses the passed parent window instead of relying on a global variable)

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.04.30 06:53:14