By default and select the first item in the Tkinter list

I want to automatically select the first item in the list. Having selected the first element, I do not mean just the default for the first element or adjust the focus on it. I already achieved this by doing self.listbox.select_set(0) . I want the default item to be selected as well. In other words, when I run my code below, I want print(value) to print(value) default selection value. If Asia is selected from the option, Japan should automatically print to the console. If Africa, Nigeria should print and Germany for Europe.

Any suggestion on how I can achieve this? Thank you

 from tkinter import * from tkinter import ttk import tkinter.messagebox class App: def __init__(self): self.master = Tk() self.di = {'Asia': ['Japan', 'China', 'Malaysia', 'India', 'Korea', 'Vietnam', 'Laos', 'Thailand', 'Singapore', 'Indonesia', 'Taiwan'], 'Europe': ['Germany', 'France', 'Switzerland'], 'Africa': ['Nigeria', 'Kenya', 'Ethiopia', 'Ghana', 'Congo', 'Senegal', 'Guinea', 'Mali', 'Cameroun', 'Benin', 'Tanzania', 'South Africa', 'Zimbabwe']} self.variable_a = StringVar() self.frame_optionmenu = ttk.Frame(self.master) self.frame_optionmenu.pack() options = sorted(self.di.keys()) self.optionmenu = ttk.OptionMenu(self.frame_optionmenu, self.variable_a, options[0], *options) self.variable_a.set('Asia') self.optionmenu.pack() self.btn = ttk.Button(self.master, text="Submit", width=8, command=self.submit) self.btn.pack() self.frame_listbox = ttk.Frame(self.master) self.frame_listbox.pack(side=RIGHT, fill=Y) self.scrollbar = Scrollbar(self.frame_listbox ) self.scrollbar.pack(side=RIGHT, fill=Y) self.listbox = Listbox(self.frame_listbox, selectmode=SINGLE, yscrollcommand=self.scrollbar.set) self.variable_a.trace('w', self.updateoptions) self.scrollbar.config(command=self.listbox.yview) self.listbox.pack() #Populate listbox for each in self.di[self.variable_a.get()]: self.listbox.insert(END, each) self.listbox.select_set(0) #This only sets focus on the first item. self.listbox.bind("<<ListboxSelect>>", self.OnSelect) self.master.mainloop() def updateoptions(self, *args): #countries = self.di[self.variable_a.get()] self.listbox.delete(0, 'end') for each in self.di[self.variable_a.get()]: self.listbox.insert(END, each) self.listbox.select_set(0) #This only sets focus on the first item. self.listbox.pack() def submit(self, *args): var = self.variable_a.get() if messagebox.askokcancel("Selection", "Confirm selection: " + var): print(var) def OnSelect(self, event): widget = event.widget value = widget.get(widget.curselection()[0]) print(value) App() 

Running Python 3.4.1

+5
source share
2 answers

The simplest solution is to <<ListboxSelect>> event at the same time as you change the selection:

 def updateoptions(self, *args): ... self.listbox.select_set(0) #This only sets focus on the first item. self.listbox.event_generate("<<ListboxSelect>>") ... 
+10
source
 # add before .mainloop() self.listbox.selection_set( first = 0 ) 

EDIT#1 2014-08-21 13:50 [UTC+0000]

Tkinter.Listbox() -es have a rather complicated MVC-Model-Part behavior. Thus, its Controller-Part .methods() more complex to handle.

Listbox() by default select-mode allows only one item to be selected, but the select-mode argument supports four parameters: SINGLE , BROWSE , MULTIPLE and EXTENDED (default is BROWSE ). Of these, the first two are single selection modes, and the last two allow you to select multiple items.

These modes differ in a subtle way.

For example, BROWSE is similar to SINGLE , but it also allows you to drag and drop .

Pressing an item in MULTIPLE mode switches its state without affecting the other selected items.

And the EXTENDED mode allows multiple selection and works like a Windows Explorer GUI file - you select one element with a simple click , several elements with the Ctrl -click combination and element ranges with Shift - click -s.

Several options can be programmed using this code:

 listbox = Listbox( aWindow, bg = 'white', font = ( 'courier', fontsz ) ) listbox.config( selectmode = EXTENDED ) # see above listbox.bind( '<Double-1>', ( lambda event: onDoubleClick() ) ) # a lambda-wrapped CallBackHANDLER() # onDoubleClick: get messages selected in listbox # not listed here selections = listbox.curselection() # tuple of digit-string(s), aTupleOfSTRINGs, where digit-string(s) range from { 0, 1, .., N-1 } selections = [ int( x ) + 1 for x in selections ] # transform string(s) to shifted int(s), make 'em { 1, 2, .., N } 

When multiple choices are enabled, the .curselection() method returns a list of string of digits indicating the relative numbers of the selected items, or returns an empty tuple if none are selected.

Beware of this method always returns a tuple of digits, even in single select mode.

Thus, symmetrically, the Listbox() .selection_set() method must have rich functionality in order to be able to configure all possible states for the <aSelectionSET> value.

QED is higher in the initial post.

+1
source

Source: https://habr.com/ru/post/1200793/


All Articles