简体   繁体   中英

Move Thru a Python List One Item at a Time

Still pretty new to Python, so my apologies in advance... I'm trying to use a button to move thru a List one item at a time. It works the first time the button is clicked and moves to the second item in the List, but subsequent clicks keep returning the same values

from tkinter import *
window=Tk()
window.title('nextArrItem')
window.geometry("300x200+10+10")

options = ["H9Iu49E6Mxs", "YuWZNV4BkkY", "mBf6kJIbXLg", "Hz-xbM6jaRY"]

print("options[0] = " + options[0])   

curItemText = options[0]
nextItemText = options[1]
curItem = 0

print('curItemText = '+curItemText)
print('nextItemText = '+nextItemText)

def nextArrItem(curItem=curItem+1):
    print("str(curItem) = "+str(curItem))

    try:
        curItemText = options[curItem]
        nextItemText = options[curItem+1]
        print('curItemText = '+curItemText)
        print('nextItemText = '+nextItemText)
        curItem = curItem + 1
    except:
        print("End of Array Reached")

nextButton = Button(window, text="Next Item", command=nextArrItem)
nextButton.place(x=130, y=110)

window.mainloop()

When the Window opens initially, these values are returned:

options[0] = H9Iu49E6Mxs
curItemText = H9Iu49E6Mxs
nextItemText = YuWZNV4BkkY

The first click returns the following:

str(curItem) = 1
curItemText = YuWZNV4BkkY
nextItemText = mBf6kJIbXLg

Subsequent clicks keep returning the same values, so it only advances the first time and I'm not sure how to fix it. Although it probably doesn't look like it, this is the culmination of a lot of work just to get it to this point but I'm not sure where to go from here. I have the feeling the solution is going to be a true Homer Simpson "D'oh!" moment but I've steered this boat into shallow waters and need someone to help me from running aground...

Thanks in advance!

Paul

You need to increment the parameter each time to the next highest value. Currently your code just feeds the nextArrItem function the same value each time.

You could also try something to put the curItem inside a mutable data type so that it can be updated from within the scope of the function call like this:

...
options = ["H9Iu49E6Mxs", "YuWZNV4BkkY", "mBf6kJIbXLg", "Hz-xbM6jaRY"]
curItem = [0]
...

def nextArrItem(label=label):
    try:
        option = options[curItem[0]]
        print(option)
        label["text"] = option   # updates label on each call
        curItem[0] += 1          # increments index for option text
    except IndexError:
       print("End of Array Reached")
...
nextButton = Button(window, text="Next Item", command=nextArrItem)
...

Another way of doing it would be to bind the curItem variable to the window itself like this:

from tkinter import *

window=Tk()
window.curItem = 0
window.title('nextArrItem')
window.geometry("300x200+10+10")

options = ["H9Iu49E6Mxs", "YuWZNV4BkkY", "mBf6kJIbXLg", "Hz-xbM6jaRY"]
label = Label(window, text=options[window.curItem])
label.place(x=130, y=50)

def nextArrItem(label=label):
    try:
        option = options[window.curItem]
        print(option)
        label["text"] = option   # updates label on each call
        window.curItem += 1          # increments index for option text
    except IndexError:
       print("End of Array Reached")

nextButton = Button(window, text="Next Item", command=nextArrItem)
nextButton.place(x=130, y=110)
window.mainloop()

The issue you have is that curItem is both a global variable and a local variable in your callback function. You only ever update the local variable, so the change doesn't persist.

Here's how you're currently setting up the local variable, as an argument with a default value:

def nextArrItem(curItem=curItem+1):

The default value comes from the global variable, but it is only evaluated once, at the time the function is defined. It does not keep checking the global value, nor do changes to the local variable in the function change the global value either.

There's a better way. You can use a global statement to make it so that your function's code can directly read and write the global variable, so that there's only one curItem that everything is accessing the same way.

def nextArrItem():
    global curItem

    # the rest can be the same

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

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