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

Tkinter ListBox报错:'StringVar'对象不可迭代问题求助

Tkinter ListBox更新失败及报错修复

问题场景

开发派对游戏Python版本,用tkinter构建GUI,包含卡组类型单选按钮和显示卡组名称的ListBox:

  • 命令行中能正常获取卡组列表,但GUI加载时仅显示第一个卡组名称
  • 点击单选按钮时控制台报错:
TypeError: 'StringVar' object is not iterable

相关代码

master_deck_list = []
deck_type_selection = tk.StringVar(value="official")

with open('cah-cards-full.json', encoding="utf8") as c:
    master_deck_list = json.loads(c.read())

def get_available_decks(master_deck_list, deck_type_selection):
    # Assign the list of deck names to deck_list
    decks_list = []
    
    for av_deck in master_deck_list:
        if deck_type_selection == 'official':
            if av_deck['official'] == True:
                decks_list.append(av_deck['name'])
        elif deck_type_selection == 'community':
            if av_deck['official'] == False:
                decks_list.append(av_deck['name'])
        elif deck_type_selection == 'all':
            decks_list.append(av_deck['name'])

        return decks_list

decklist = get_available_decks(master_deck_list, deck_type_selection="official")
list_items = tk.StringVar(value=decklist)

def update_decklist(list_items):
    for item in list_items:
        listbox.insert(tk.END, item)

...

# Deck type radio buttons
radio_1 = tk.Radiobutton(decktypes_frame, text="Official", variable=deck_type_selection, value="official", command=lambda: update_decklist(list_items))
radio_1.grid(column=0, row=0, padx=5, pady=5)
radio_2 = tk.Radiobutton(decktypes_frame, text="Community", variable=deck_type_selection, value="community", command=lambda: update_decklist(list_items))
radio_2.grid(column=1, row=0, padx=5, pady=5)
radio_3 = tk.Radiobutton(decktypes_frame, text="All", variable=deck_type_selection, value="all", command=lambda: update_decklist(list_items))
radio_3.grid(column=2, row=0, padx=5, pady=5)

# decksframe holds the available and selected decks lists
decksframe = tk.LabelFrame(main, text="Available Decks")
decksframe.columnconfigure(0, weight=3)
decksframe.columnconfigure(1, weight=3)

# Available Decks
listbox = tk.Listbox(decksframe, selectmode="multiple", listvariable=list_items, exportselection=0)
listbox.grid(column=0, row=0, padx=5, pady=5)

完整回溯信息

Exception in Tkinter callback
Traceback (most recent call last):
  File "C:\Program Files\WindowsApps\PythonSoftwareFoundation.Python.3.8_3.8.2800.0_x64__qbz5n2kfra8p0\lib\tkinter\__init__.py", line 1892, in __call__
    return self.func(*args)
  File "setup.py", line 63, in <lambda>
    radio_2 = tk.Radiobutton(decktypes_frame, text="Community", variable=deck_type_selection, value="community", command=lambda: update_decklist(list_items))
  File "setup.py", line 40, in update_decklist
    for item in list_items:
TypeError: 'StringVar' object is not iterable

修复步骤

1. 修正get_available_decks的返回逻辑

原函数中return decks_list缩进在for循环内部,导致仅返回第一个符合条件的卡组。将return移到循环外:

def get_available_decks(master_deck_list, deck_type_selection):
    decks_list = []
    for av_deck in master_deck_list:
        if deck_type_selection == 'official':
            if av_deck['official'] == True:
                decks_list.append(av_deck['name'])
        elif deck_type_selection == 'community':
            if av_deck['official'] == False:
                decks_list.append(av_deck['name'])
        elif deck_type_selection == 'all':
            decks_list.append(av_deck['name'])
    # 移到循环外,确保遍历所有卡组后返回完整列表
    return decks_list

2. 重写update_decklist函数

原函数错误地遍历StringVar对象,正确逻辑应为获取当前选中类型、重新获取卡组列表、更新ListBox:

def update_decklist():
    # 获取单选按钮选中的卡组类型
    selected_type = deck_type_selection.get()
    # 获取对应卡组列表
    new_decks = get_available_decks(master_deck_list, selected_type)
    # 清空ListBox原有内容
    listbox.delete(0, tk.END)
    # 插入新卡组列表
    for item in new_decks:
        listbox.insert(tk.END, item)
    # 同步更新StringVar,保持与ListBox数据一致
    list_items.set(new_decks)

3. 修正单选按钮的command参数

不需要传递list_items,直接绑定update_decklist函数:

radio_1 = tk.Radiobutton(decktypes_frame, text="Official", variable=deck_type_selection, value="official", command=update_decklist)
radio_1.grid(column=0, row=0, padx=5, pady=5)
radio_2 = tk.Radiobutton(decktypes_frame, text="Community", variable=deck_type_selection, value="community", command=update_decklist)
radio_2.grid(column=1, row=0, padx=5, pady=5)
radio_3 = tk.Radiobutton(decktypes_frame, text="All", variable=deck_type_selection, value="all", command=update_decklist)
radio_3.grid(column=2, row=0, padx=5, pady=5)

效果验证

修复后:

  • 窗口加载时会显示所有官方卡组名称
  • 点击不同单选按钮,ListBox会实时更新对应类型的卡组列表
  • 不再出现TypeError报错

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.27 20:08:15