创建抽认卡项目时遇'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()
错误原因
- Tkinter的
Listbox构造函数第二个参数接受的是配置参数字典,你直接传入StringVar对象,导致Tkinter尝试将其当作字典遍历,触发"not iterable"错误。 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
相关产品推荐
相关产品推荐

