所以我在TkInter(Python 3.4.3)中进行数学测试。我想对所有问题只使用一帧。我有一个列表,其中包含从另一个.py导入的所有字符串(QStringList
),它们用作标签的文本变量。
当用户按 Return 或按钮时,我想迭代到列表中的下一个项目,因此显示了一个新问题。 使用我当前的代码,我只能成功执行一次。大概是因为' CurrentQ'变量每次都设置回0。 如何这样做,以便每次调用该函数时,都会显示下一个列表项?
此代码位于我的TestPage(tk.Frame):
课程中。
def __init__(self,parent,controller):
tk.Frame.__init__(self,parent)
CurrentQ = 0
#QUESTION LABEL
self.CurrentQStringVar = tk.StringVar()
self.CurrentQString = tk.Label(self, textvariable=self.CurrentQStringVar,
anchor='w',fg="black", bg="yellow", font=STANDARD_FONT)
self.CurrentQString.grid(column=0,row=0,columnspan=2, sticky='EW')
self.CurrentQStringVar.set(QStringList[CurrentQ])
#ANSWER ENTRY BOX
self.UserAnsEntryVar = tk.StringVar()
self.UserAnsEntry = tk.Entry(self,textvariable=self.UserAnsEntryVar)
self.UserAnsEntry.grid(column=0,row=1,sticky='EW')
self.UserAnsEntry.bind("<Return>",
lambda event, CurrentQ=CurrentQ:
self.TestEnterKey(self,CurrentQ))
self.UserAnsEntryVar.set("")
#ANSWER BUTTON
self.UserAnsButtonVar = tk.StringVar()
self.UserAnsButton = ttk.Button(self,text="ENTER",
command= lambda: self.TestEnterKey(self,CurrentQ))
self.UserAnsButton.grid(column=0,row=2,columnspan=2, stick='EW')
def TestEnterKey(self,event,CurrentQ):
CurrentQ += 1
self.CurrentQStringVar.set(QStringList[CurrentQ])
return CurrentQ
我尝试在函数中使用CurrentQ
作为参数,但也许我必须使用lambda
。
编辑:我的实际QStringList非常长,并包含其他(随机生成的)变量。所以对于这一点,我想最好还是......
QStringList = ["Q1","Q2","Q3","Q4","Q5","Q6","Q7","Q8","Q9","Q10"]
答案 0 :(得分:0)
首先,不要使用lambda
。 Lambda有它的用途,但你很少在Tkinter程序中使用它,并且通常不会让代码更复杂而不给予任何回报。
相反,在需要时,使从绑定和按钮调用的函数获取所需的数据。由于绑定发送事件而命令按钮不发送,只需使事件参数可选。
另外,将CurrentQ
设为对象的属性,以便它可以轻松访问,并且不必传递。
def __init__(self,parent,controller):
...
self.CurrentQ = 0
...
self.UserAnsEntry.bind("<Return>",self.TestEnterKey)
...
self.UserAnsButton = ttk.Button(self,text="ENTER", command=self.TestEnterKey)
...
def TestEnterKey(self,event=None):
self.CurrentQ += 1
self.CurrentQStringVar.set(QStringList[self.CurrentQ])
您可以循环查看问题列表的另一种方法是始终使用列表中的第一项,然后将第一项移到最后。 Python有一个类似的功能,让你无限期地遍历列表。见itertools.cycle。
例如:
import itertools
...
self.questions = itertools.cycle(self.QStringList)
...
# this will always return the next question, looping
# back over the list as needed
next_question = self.questions.next()
最后,您可能需要使用带有标签的StringVar
来考虑 not 。除非您在多个地方使用StringVar
,否则确实没有必要。如果没有它,您仍然可以更改标签中的文本,但是您必须在项目中减少一个必须管理的对象。
例如:
question = self.questions.next()
self.CurrentQString.configure(text=question)