Creating a choicelist dialog box with tkinter

Question:

I am trying to make using tkinter a function similar to buttonbox of easygui (http://easygui.sourceforge.net/tutorial.html#buttonbox) which I should be able to call from both console and gui applications:

from tkinter import *
def mychoicebox(choicelist): 
    def buttonfn(): 
        return var.get()
    choicewin = Tk()
    choicewin.resizable(False, False)
    choicewin.title("ChoiceBox")

    Label(choicewin, text="Select an item:").grid(row=0, column=0, sticky="W")

    var = StringVar(choicewin)
    var.set('No data') # default option
    popupMenu = OptionMenu(choicewin, var, *choicelist)
    popupMenu.grid(sticky=N+S+E+W, row =1, column = 0)

    Button(choicewin, text='Done', command=buttonfn).grid(row=2, column=0)
    choicewin.mainloop()

Testing:

reply = mychoicebox(['one','two','three'])
print("reply:", reply)

It creates a window with label, choicelist and buttons but it does not return the selected item when “Done” button is pressed. How can I make this work?

Asked By: rnso

||

Answers:

It’s a bit rearranged into a class, but is this what you were wanting to do?

from tkinter import *

class Choices:

    def __init__(self, parent, choicelist):

        Label(choicewin, text="Select an item:").grid(row=0, column=0, sticky="W")

        self.var = StringVar()
        self.var.set('No data') # default option
        popupMenu = OptionMenu(choicewin, self.var, *choicelist)
        popupMenu.grid(sticky=N+S+E+W, row =1, column = 0)

        Button(choicewin, text='Done', command=self.buttonfn).grid(row=2, column=0)

    def buttonfn(self): 
        print(self.var.get())

if __name__ == '__main__':
    choicewin = Tk()
    choicewin.resizable(False, False)
    choicewin.title("ChoiceBox")
    app = Choices(choicewin, ['one','two','three'])
    choicewin.mainloop()
Answered By: Ron Norris

Minor modifications will make it work like you want. The result was getting returned by the button function, but not by the outer function. By making it global within your function, the outer function is able to return it. Note: you must also break out of the mainloop for the outer function to complete:

from tkinter import *

def mychoicebox(choicelist):
    global result

    def buttonfn():
        global result
        result = var.get()
        choicewin.quit()

    choicewin = Tk()
    choicewin.resizable(False, False)
    choicewin.title("ChoiceBox")

    Label(choicewin, text="Select an item:").grid(row=0, column=0, sticky="W")

    var = StringVar(choicewin)
    var.set("No data")  # default option
    popupMenu = OptionMenu(choicewin, var, *choicelist)
    popupMenu.grid(sticky=N + S + E + W, row=1, column=0)

    Button(choicewin, text="Done", command=buttonfn).grid(row=2, column=0)
    choicewin.mainloop()
    return result

# Testing:

reply = mychoicebox(["one", "two", "three"])
print("reply:", reply)
Answered By: RufusVS