How do I let .selection_set() set the selection bar to the selected shuffled item in the listbox? Using .curselection()[0] only returns the index of the current selected item in the listbox, but when I place a button that links to the shuffled items of the listbox, the selection bar isn't set according to the selected item. What I'm trying to achieve is something like a next button, .curselection()[0] 1. But instead of going down the list, I need it to go according to the selected shuffled item, something like .curselection()[0] "the index of the selected shuffled item". Below is a runnable code of what I'm trying to explain:
import tkinter as tk
from random import shuffle
root = tk.Tk()
root.geometry('300x200')
root.resizable(False, False)
root.title('Listbox')
is_shuffling = False
item_index = 0
langs = ['Java', 'C#', 'C', 'C ', 'Python',
'Go', 'JavaScript', 'PHP', 'Swift']
langs_var = tk.StringVar(value=langs)
listbox = tk.Listbox(root, listvariable=langs_var, height=6)
listbox.grid(column=0, row=0, sticky='nwes')
bottom_frame = tk.Frame()
bottom_frame.grid(row=1, column=0, sticky="ew")
bottom_frame.grid_columnconfigure(2, weight=1)
bottom_frame.grid_rowconfigure(0, weight=1)
root.rowconfigure(0, weight=1)
root.columnconfigure(0, weight=1)
shuffle(langs)
def go_next():
global is_shuffling
global langs
shuffle(langs)
if is_shuffling:
item_index = listbox.curselection()[0]
listbox.selection_clear(0, tk.END)
listbox.selection_set(item_index)
listbox.activate(item_index)
print(langs)
else:
try:
idx = listbox.curselection()[0] 1
listbox.selection_clear(0, tk.END)
listbox.selection_set(idx)
listbox.activate(idx)
except IndexError:
listbox.selection_set(0)
listbox.activate(0)
def toggle_shuffle():
global is_shuffling
if is_shuffling:
shuffle_btn.config(text="Shuffle Off")
is_shuffling = False
else:
shuffle_btn.config(text="Shuffle On")
is_shuffling = True
shuffle_btn = tk.Button(bottom_frame, relief=tk.SUNKEN, text="Shuffle", bg="silver", highlightthickness=0, bd=0, command=toggle_shuffle)
shuffle_btn.grid(row=1, column=0)
next_btn = tk.Button(bottom_frame, relief=tk.SUNKEN, text="Next Button", bg="silver", highlightthickness=0, bd=0, command=go_next)
next_btn.grid(row=1, column=1, padx=10)
print(langs)
root.mainloop()
You can see that when the shuffle button is pressed, pressing the next button won't set the selection bar to the selected shuffled item from the list.
CodePudding user response:
You need to get the random index, not shuffle the lists, because shuffling entire list might not be what you want.
from random import randint
def go_next():
global is_shuffling
if is_shuffling:
rand = randint(0,listbox.size()-1) # Get random index within range
listbox.selection_clear(0, tk.END)
listbox.selection_set(rand) # Set the index
listbox.activate(rand)
else:
try:
idx = listbox.curselection()[0] 1
listbox.selection_clear(0, tk.END)
listbox.selection_set(idx)
listbox.activate(idx)
except IndexError:
listbox.selection_set(0)
listbox.activate(0)
