TypeError:“StringVar”对象不可迭代 - tkinter ListBox()

问题描述 投票:0回答:1

我正在构建一款流行派对游戏的 Python 版本,并且我正在使用 tkinter 构建带有玩家名称和游戏首选项的设置 GUI。当我运行代码时,窗口会打开,除了一件关键的事情外,它看起来很正确。

有单选按钮可以选择牌组类型,还有一个列表框用于显示游戏中牌组的名称,只要单击单选按钮,该列表框就会更新。

获取套牌名称列表在命令行上工作正常,但我无法使其在 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
python tkinter radio-button listbox
1个回答
0
投票

错误消息的含义与它所说的完全一样。

list_items
不是一个列表,也不是一个字符串,它是一个
StringVar
。你不能这样做
for item in list_items
因为
list_items
不支持迭代。

解决方案似乎是简单地将

list_items
设置为
decklist
(或者直接扔掉
list_items
并直接使用
decklist
)。然后,只需将项目插入列表框中,而不是使用
listvariable
。例如:

listbox = tk.Listbox(decksframe, selectmode="multiple", exportselection=0)
listbox.insert("end", *decklist)
© www.soinside.com 2019 - 2024. All rights reserved.