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

创建抽认卡项目时遇'StringVar'不可迭代错误求助

解决Tkinter中argument of type 'StringVar' is not iterable错误

问题场景

开发抽认卡项目时,尝试读取flashdata/目录下所有文本文件内容,将每行转为列表后存入StringVar,再创建对应的Listbox组件并布局,触发了argument of type 'StringVar' is not iterable错误。

出错代码片段

for i in res:
    with open(f"flashdata/{res[e]}", "r") as f:
        g = []
        f.seek(0)
        g = StringVar(tp, f.read().splitlines())
        tplist = Listbox(tp, g)
        tplist.pack()
        e += 1
        f.close()

完整报错信息

Exception in Tkinter callback
Traceback (most recent call last):
  File "/usr/lib/python3.10/tkinter/__init__.py", line 1921, in __call__
    return self.func(*args)
  File "/home/shonky/Desktop/Python Programs/Flashcard Studio/(m) prgmctk copy 2.py", line 25, in review_button
    tplist = Listbox(tp, g)
  File "/usr/lib/python3.10/tkinter/__init__.py", line 3191, in __init__
    Widget.__init__(self, master, 'listbox', cnf, kw)
  File "/usr/lib/python3.10/tkinter/__init__.py", line 2595, in __init__
    BaseWidget._setup(self, master, cnf)
  File "/usr/lib/python3.10/tkinter/__init__.py", line 2566, in _setup
    if 'name' in cnf:
TypeError: argument of type 'StringVar' is not iterable

项目完整代码

import requests
from html import unescape
from bs4 import BeautifulSoup 
from tkinter import *
import os

def review_button():
    tp = Toplevel()
    tp.title("Flashcard_Studio/Sets")
    tp.minsize(200,200)
    tp.maxsize(200,200)
    e = 0
    c = 0
    res = []
    for path in os.listdir("flashdata/"):
        c += 1
        res.append(path)
    for i in res:
        with open(f"flashdata/{res[e]}", "r") as f:
            #for num in f: pass
            g = []
            f.seek(0)
            g = StringVar(tp, f.read().splitlines())
            #g = StringVar(tp, g)
            tplist = Listbox(tp, g)
            tplist.pack()
            e += 1
            f.close()
    label2 = Label(tp, text = "Sets:")
    label2.pack()

def scrape():
    flshlinelen = 0
    print("Button pressed")
    HEADERS = {
    "User-Agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/87.0.4280.88 Safari/537.36"
    }
    soup = BeautifulSoup(requests.get(entry_text.get(), headers=HEADERS).text, "html.parser")
    flashcard_title = soup.find("h1").text

    f = open(f'flashdata/{flashcard_title}.txt', 'w')

    flsh = soup.find_all("div", class_ = "SetPageTerms-term")
    flsh += soup.find_all("div", class_ = "SetPageTerms-term SetPageTerms-term--beyondSignupThreshold")

    for index, flashcards in enumerate(flsh):
        flshlst = flsh[index]
        flash1 = flshlst.find("a", class_ = "SetPageTerm-wordText").text
        flash2 = flshlst.find("a", class_ = "SetPageTerm-definitionText").text
        with open(f"flashdata/{flashcard_title}.txt", "a") as f:
            f.write(f"w: {flash1}\n")
            f.write(f"def: {flash2}\n")
            flshlinelen += 2
            print(f"w: {flash1}\n")
            print(f"def: {flash2}\n")
    opener = open("flashdata/" + flashcard_title + ".txt", "a")
    opener.write(str(flshlinelen))
    print(flshlinelen)
    opener.close()
    f.close()
    x = open(f"flashdata/{flashcard_title}.txt", "r")
    print(x.read())

root = Tk()

root.title("Flashcard_Studio/Scrape")
root.minsize(700,100)
root.maxsize(700,100)

label = Label(text = "Quizlet Link:")
entry_text = StringVar()
entry = Entry(textvariable = entry_text, width = 75)
button1 = Button(text = "Get Flashcards", command = scrape)
button2 = Button(root, text = "Review Sets", command = review_button)
label.pack()
entry.pack()
button1.pack()
button2.pack()


root.mainloop()

错误原因

  1. Tkinter的Listbox构造函数第二个参数接受的是配置参数字典,你直接传入StringVar对象,导致Tkinter尝试将其当作字典遍历,触发"not iterable"错误。
  2. StringVar只能存储单个字符串,无法直接保存列表数据,这是逻辑上的误区。

修复方案

直接使用文件读取的列表数据,通过insert()方法添加到Listbox中,同时优化循环逻辑:

修复后的review_button函数代码:

def review_button():
    tp = Toplevel()
    tp.title("Flashcard_Studio/Sets")
    tp.minsize(200,200)
    tp.maxsize(200,200)
    
    label2 = Label(tp, text = "Sets:")
    label2.pack()
    
    for filename in os.listdir("flashdata/"):
        file_path = f"flashdata/{filename}"
        with open(file_path, "r") as f:
            lines = f.read().splitlines()
            tplist = Listbox(tp)
            # 将每行内容插入Listbox
            for line in lines:
                tplist.insert(END, line)
            tplist.pack()

额外优化点

  • 移除冗余的索引变量e和计数变量c,直接遍历目录文件更简洁。
  • 将label2移到Listbox之前,符合正常布局逻辑。
  • 无需手动调用f.close(),with语句会自动管理文件资源。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.27 21:37:47