420fedoras
420fedoras

Reputation: 325

Call a function on button press using value from listbox Tkinter

I want to use the value selected from my listbox in a button's command, so that no code executes until the "Go" button is pressed.

So far I have only seen that a listbox executes code on selection of an element by binding to <>. This seems dumb to me, surely a program should have some sort of two stage selection to make sure the user is selecting exactly what they want (tangent, sorry).

I have so far tried to create a variable for the current selection using .curselection()[0] and .get but I get an index error from this (possibly because there is no selection initially). Then if I set an initial selection, I cant change it and it will always execute based on that selection.

Surely this should be easy and I'm missing something.

[EDIT] Adding code dump as suggested:

class DataVisualiser:
    def __init__(self, master):
        master.minsize(width=600, height=400)
        frame = Frame(master)
        frame.grid()

        # Histogram Generator
        hist_options = ["Cat vs. Dog", "Cat Breed", "Dog Breed", "Cat Name", "Dog Name", "Cat Location",
                        "Dog Location", "Cat Registration", "Dog Registration"]
        hist_dd = Listbox(master, bg="#cfcfcf", fg="black", font="Helvetica", height=5, selectmode=SINGLE)
        for o in hist_options:
            hist_dd.insert(0, o)
        hist_dd.grid(row=0, column=0)
        hist_dd.selection_set(first=0)
        hist_scroll = Scrollbar(master, orient=VERTICAL)
        hist_dd["yscrollcommand"] = hist_scroll.set
        hist_scroll["command"] = hist_dd.yview
        hist_scroll.grid(row=0, column=1, rowspan=7, sticky=N+S)
        # scrollbar from: https://www.youtube.com/watch?v=xNLdB0jY1Rg
        # HERE: I want to pass the value from the listbox to another function via this button
        hist_gen = Button(master, text="Go!",
                          command=lambda group=hist_dd.get(hist_dd.curselection()[0]): generate_histogram(group))
        # still need to fully implement this
        hist_gen.grid(row=6, column=0, sticky=W+E)    

def generate_histogram(group):
    print(group)
    return None

root = Tk()
dv = DataVisualiser(root)
root.mainloop()

Upvotes: 0

Views: 838

Answers (2)

Nidhin_toms
Nidhin_toms

Reputation: 737

why don't you initialize a global variable in the listBox function which stores the value that is selected in the listbox and then the callBack function of the button can use that global variable?

The code below just illustrates how your code can work.

def getRuleAfterButtonPress(valueFromListbox):
    for index,rows in excelFile.iterrows():
        if (int(valueFromListbox)==int(rows[columns[0]][5:10])):
            rightSideText2.delete(1.0,END)
            rightSideText2.insert(END,rows[columns[7]])

def onSelectFromListBox(evt):
    # Note here that Tkinter passes an event object to onselect()
    w = evt.widget
    index0 = int(w.curselection()[0])
    global valueFromListbox
    valueFromListbox = w.get(index0)

Upvotes: 0

Khristos
Khristos

Reputation: 983

Since your DataVisualiser is a class, it will be better to make other functions methods of the class instead. Your variables (or some of them) too should be made class instance variables to avoid using the global keyword.

I made the group variable an instance variable using the self keyword (self.group), and created a method, select, which updates the that variable anytime the listbox selection changes. Also made the function generate_histogram a class method. You may have to make some of the other variables instance variables as well based on the overall program goal.

The updated code below has comments to explain some of the other changes/additions. You might need to change the import statement depending on the version of Python you are using.

from Tkinter import *

class DataVisualiser:
    def __init__(self, master):
        master.minsize(width=600, height=400)
        frame = Frame(master)
        frame.grid()

        # Histogram Generator
        hist_options = ["Cat vs. Dog", "Cat Breed", "Dog Breed", "Cat Name", "Dog Name", "Cat Location",
                        "Dog Location", "Cat Registration", "Dog Registration"]
        hist_dd = Listbox(master, bg="#cfcfcf", fg="black", font="Helvetica", height=5, selectmode=SINGLE)
        for o in hist_options:
            hist_dd.insert(0, o)
        hist_dd.grid(row=0, column=0)
        hist_dd.selection_set(first=0)
        hist_scroll = Scrollbar(master, orient=VERTICAL)
        hist_dd["yscrollcommand"] = hist_scroll.set
        hist_scroll["command"] = hist_dd.yview
        hist_scroll.grid(row=0, column=1, rowspan=7, sticky=N+S)

        # scrollbar from: https://www.youtube.com/watch?v=xNLdB0jY1Rg
        # HERE: I want to pass the value from the listbox to another function via this button
        self.group = hist_dd.get(hist_dd.curselection()[0]) #make group a class variable

        # don't use default keyword parameters i.e, group= .....
        hist_gen = Button(master, text="Go!",
                          command=lambda: self.generate_histogram(self.group))
        # still need to fully implement this
        hist_gen.grid(row=6, column=0, sticky=W+E)  
        hist_dd.bind('<<ListboxSelect>>', self.select) # bind selecction event to listbox


    #method to change the 'group' variable anytime a listbox selection changes
    def select(self, event):
        widget = event.widget
        selection=widget.curselection()
        self.group = widget.get(selection[0])


    #class method
    def generate_histogram(self, group):
        print(group)
        return None

root = Tk()
dv = DataVisualiser(root)
root.mainloop()

Upvotes: 1

Related Questions