Home > Software design >  How to set the selection bar based on the index of the shuffled items in the tkinter listbox
How to set the selection bar based on the index of the shuffled items in the tkinter listbox

Time:02-04

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)
  •  Tags:  
  • Related