簡體   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