0

Could somebody help me with this. I am passing values from one listbox to another and back again in tkinter, but I need to output the current list (values in box on right).The values in this box will change because they can be moved back to the original box (left). I have tried using the return statement to return the current list but keep getting nothing printed out

from tkinter import *
from tkinter import ttk

my_window = Tk()

my_frame_in = Frame(my_window)
my_frame_in.grid(row=0, column=0)
my_frame_out = Frame(my_window)
my_frame_out.grid(row=0, column=1)

listbox_events = Listbox(my_frame_in, height='5')
listbox_events.grid(row=0, column=0, padx=10, pady=10)
listbox_events_filtered = Listbox(my_frame_out, height='5')
listbox_events_filtered.grid(row=0, column=2, padx=(0, 10), pady=10)
my_instructions = Label(my_window, text='Use arrow keys to move selected items')
my_instructions.grid(row=1, column=0, columnspan=3, pady=(0, 10))

my_list_events = ['A', 'B', 'C', 'D']

for item in my_list_events:
    listbox_events.insert(END, item)

current_list = []


def select_events():
    listbox_events_filtered.insert(END, listbox_events.get(ANCHOR))
    listbox_events.delete(ANCHOR)
    current_list.append(ANCHOR)
    return current_list


def deselect_events(event=None):
    listbox_events.insert(END, listbox_events_filtered.get(ANCHOR))
    listbox_events_filtered.delete(ANCHOR)
# ref https://effbot.org/tkinterbook/tkinter-events-and-bindings.htm


listbox_events.bind('<Right>', select_events)
listbox_events.bind('<Left>', deselect_events)

for item in current_list:
    print(item)

mainloop()
Sid
  • 153
  • 3
  • 15

1 Answers1

1

This statement returns a tuple containing all of the values in the second listbox.

listbox_events_filtered.get(0,END)

However, there are also a number of other issues with your code:

def select_events() also needs to be def select_events(event=None)

You are binding the wrong listbox to deselect_events; it should be listbox_events_filtered.bind('<Left>', deselect_events)

the current_list in select_events() is a local variable and does not affect the current_list outside of the function.

returning current_list at the end of select_events() does nothing as you are not assigning the function to anything.

Finally,

for item in current_list:
    print(item)

will only be run once as mainloop() only loops tkinter events.

With all of that in mind, you should change your code to something like this instead:

from tkinter import *
from tkinter import ttk

my_window = Tk()

my_frame_in = Frame(my_window)
my_frame_in.grid(row=0, column=0)
my_frame_out = Frame(my_window)
my_frame_out.grid(row=0, column=1)

listbox_events = Listbox(my_frame_in, height='5')
listbox_events.grid(row=0, column=0, padx=10, pady=10)
listbox_events_filtered = Listbox(my_frame_out, height='5')
listbox_events_filtered.grid(row=0, column=2, padx=(0, 10), pady=10)
my_instructions = Label(my_window, text='Use arrow keys to move selected items')
my_instructions.grid(row=1, column=0, columnspan=3, pady=(0, 10))

my_list_events = ['A', 'B', 'C', 'D']

for item in my_list_events:
    listbox_events.insert(END, item)

current_list = []


def select_events(event=None):
    listbox_events_filtered.insert(END, listbox_events.get(ANCHOR))
    listbox_events.delete(ANCHOR)
    current_list.append(ANCHOR)
    for item in listbox_events_filtered.get(0,END):
        print(item)


def deselect_events(event=None):
    listbox_events.insert(END, listbox_events_filtered.get(ANCHOR))
    listbox_events_filtered.delete(ANCHOR)
    for item in listbox_events_filtered.get(0,END):
        print(item)


listbox_events.bind('<Right>', select_events)
listbox_events_filtered.bind('<Left>', deselect_events)

mainloop()

Hope this answer can allow you to solve your problems :)

TheFluffDragon9
  • 514
  • 5
  • 11
  • Thanks -I thought I understood at first but confused again - how do i return current_list out of that function? If i type print(current_list) so I can use outside the code if I type print(current_list) I just get a []. Sorry for this I am new to Python – Sid May 01 '20 at 13:37
  • To do that, you should first write `global current_list` at the start of both functions to indicate that you mean the `current_list` in the rest of the code. Then, instead of having `current_list.append(ANCHOR)`, use `current_list = list(listbox_events_filtered.get(0,END))`. – TheFluffDragon9 May 01 '20 at 13:50
  • Thanks for answering again but still having problems- I have included the corrections you mention but still cant get anything from the print(current_list) statement (which i have inserted just before mainloop - do I need a return statement ?Ive been trying them but cant get it to work – Sid May 01 '20 at 14:10
  • Sorry for late reply, haven't been on stack overflow recently; as aforementioned, Tk.mainloop() only continues to handle the tkinter events and doesn't loop the code before it. This means that your print statement will only be executed once which will be before you start changing what is in the listboxes. To run code during the tkinter mainloop, I suggest you look into the [tk.after() method](https://stackoverflow.com/questions/25753632/tkinter-how-to-use-after-method) or use threading. – TheFluffDragon9 May 03 '20 at 17:20