繁体   English   中英

使用按钮和绑定反复遍历列表

[英]Repeatedly iterating through a list, with buttons and bindings

因此,我正在TkInter(Python 3.4.3)中进行数学测试。 我只想对所有问题使用一帧。 我有一个包含所有字符串( QStringList ,从另一个.py导入)的列表,这些字符串用作标签的文本变量。

当用户按下Return或Button时,我想遍历列表中的下一个项目,因此显示了一个新问题。 使用当前的代码,我只能成功执行一次。 大概是因为“ 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"]

首先,不要使用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 除非您在多个地方使用StringVar ,否则实际上没有必要。 没有它,您仍然可以更改标签中的文本,但是项目中要管理的对象少了一个。

例如:

question = self.questions.next()
self.CurrentQString.configure(text=question)

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM