Extracting a list of items from tkinter.Listbox

12,233

You cannot use a StringVar as the target of the listvariable attribute. As your code shows, this causes the list to be converted to a string.

What you can do, however, is use an instance of tk.Variable instead. Variable is the base class for StringVar. The base implementation of get will not coerce the value to a string.

name1 = ['Peter', 'Scotty', 'Walter', 'Scott', 'Mary']
self.lb1_values = tk.Variable(value=name1)
self.listbox1 = tk.Listbox(self, listvariable=self.lb1_values)
...
e1 = self.lb1_values.get()
print('e1 = ', e1)
print('type(e1) = ', type(e1))
print('e1 = ', e1)

The above yields this output:

e1 =  ('Peter', 'Scotty', 'Walter', 'Scott', 'Mary')
type(e1) =  <class 'tuple'>
e1 =  ('Peter', 'Scotty', 'Walter', 'Scott', 'Mary')

For e2 and e3 you have to jump through an extra hoop. The cget method unfortunately returns the internal variable name rather than a reference to the variable object. To get the value of a variable by name you need to use the widget method getvar.

For example:

e2 = self.listbox1.cget('listvariable')
print('\ne2 = ', e2)
print('type(e2) = ', type(e2))
print('e2 = ', self.getvar(e2))

The above yields this output:

e2 =  PY_VAR0
type(e2) =  <class 'str'>
e2 =  ('Peter', 'Scotty', 'Walter', 'Scott', 'Mary')
Share:
12,233
Sun Bear
Author by

Sun Bear

Updated on July 03, 2022

Comments

  • Sun Bear
    Sun Bear almost 2 years

    I wrote the following tkinter script to understand how to add a list of data into a tkinter.Listbox widget. I discovered 2 methods for doing so.

    Next, I wanted to extract the same list from the tkinter.Listbox widget. Out of the 4 different approaches, I only managed to get the 4th approach (i.e. e4) to work.

    How can I get approaches e1, e2 and e3 to work? The end goal is to get the same list that was initially supplied to the tkinter.Listbox widget.

    Test Script:

    import tkinter as tk # Python 3 tkinter modules
    import tkinter.ttk as ttk
    
    class App(ttk.Frame):
        def __init__(self, parent, *args, **kwargs):
            # 1. Initialise Frame
            ttk.Frame.__init__(self, parent)
            self.parent = parent
    
            # Method1
            name1 = ['Peter', 'Scotty', 'Walter', 'Scott', 'Mary']
            self.lb1_values = tk.StringVar(value=name1)
            self.listbox1 = tk.Listbox(self, listvariable=self.lb1_values)
    
            # Method2
            self.listbox2 = tk.Listbox(self)
            name2 = ['Sarah', 'Sean', 'Mora', 'Mori', 'Mary']
            for item in name2:
                self.listbox2.insert(tk.END, item)
    
            self.listbox1.grid(in_=self, row=0, column=0, sticky='nsew')
            self.listbox2.grid(in_=self, row=0, column=1, sticky='nsew')
    
            # Extract values from listbox and covert to a list
            e1 = self.lb1_values.get()
            print('e1 = ', e1)
            print('type(e1) = ', type(e1))
            e1 = e1.strip(',')
            print('e1 = ', e1)
    
            e2 = self.listbox1.cget('listvariable')
            print('\ne2 = ', e2)
            print('type(e2) = ', type(e2))
            e2 = e2.split(',')
            print('e2 = ', e2)
    
            e3 = self.listbox2.cget('listvariable')
            print('\ne3 = ', e3)
            print('type(e3) = ', type(e3))
    
            e4 = self.listbox2.get(0, tk.END)
            print('\ne4 = ', e4)
            print('type(e4) = ', type(e4))
            e4 = list(e4)
            print('e4 = ', e4)    
    
    
    if __name__ == '__main__':
        root = tk.Tk()
        root.title('App'), root.geometry('400x200')
        app = App(root)
        app.grid(row=0, column=0, sticky='nsew')
        #root.mainloop()
    

    Output:

    e1 =  ('Peter', 'Scotty', 'Walter', 'Scott', 'Mary')
    type(e1) =  <class 'str'>
    e1 =  ('Peter', 'Scotty', 'Walter', 'Scott', 'Mary')
    
    e2 =  PY_VAR0
    type(e2) =  <class 'str'>
    e2 =  ['PY_VAR0']
    
    e3 =  
    type(e3) =  <class 'str'>
    
    e4 =  ('Sarah', 'Sean', 'Mora', 'Mori', 'Mary')
    type(e4) =  <class 'tuple'>
    e4 =  ['Sarah', 'Sean', 'Mora', 'Mori', 'Mary']