4

How can I tweak this so that if xyz17 is selected from the Menu the function xyz17() is run?

I'm aware of command = xyz17 but I'm not sure how to make that dynamic so that it depends on the menu selection.

from tkinter import *

def xyz17():
    print('xyz17')
def abc27():
    print('abc27')
def qwe90():
    print('qwe90')
def uio19():
    print('uio19')
def jkl09():
    print('jkl09')
def zxc28():
    print('zxc28')

class Menu(OptionMenu):
    def __init__(self, master, status, *options):
        self.var = StringVar(master)
        self.var.set(status)
        OptionMenu.__init__(self, master, self.var, *options)

def main():        
    TopFrame = Frame(root)
    TopFrame.pack()

    Menu1 = Menu(TopFrame, 'xyz', 'xyz17','abc27','qwe90')
    Menu2 = Menu(TopFrame, 'uio', 'uio19','jkl09','zxc28')

    Menu1.pack()
    Menu2.pack()

root = Tk()
main()
root.mainloop()

Please note that the functions each priniting the value is just for an example, I would like the code to run the function itself. I'm aware of this:

class Menu(OptionMenu):
    def __init__(self, master, status, *options):
        self.var = StringVar(master)
        self.var.set(status)
        OptionMenu.__init__(self, master, self.var, *options, command=self.func)
    def func(self,value):
        print (value)

But, this isn't relevant to my scenario as it simply just gets the value and prints it, and I would like it to actually run the function itself.

Nae
  • 14,209
  • 7
  • 52
  • 79
jim bob
  • 53
  • 6
  • @Nae I have fixed the error, please see the edit. – jim bob Jan 25 '18 at 13:46
  • @Nae No i do not use a `mainloop` and the GUI is still being displayed. I have added that now since I didn't know that it may not display the GUI for others. – jim bob Jan 25 '18 at 13:56
  • If you're using IDLE it may be running its own mainloop. – Nae Jan 25 '18 at 13:56
  • 1
    Oh right okay. That is what I'm using. – jim bob Jan 25 '18 at 13:57
  • Are your methods `xyz17` ... `zxc28` completely different methods or similar? – Nae Jan 25 '18 at 13:59
  • 1
    @Nae In my actual code there are no `xyz17` i just added that for an example. In my code theres a dropdown menu and what I would like is when an option is selected that function is ran. Also the functions doesn't just print the value this is just for example. – jim bob Jan 25 '18 at 14:01
  • I just made an edit now, I think that will explain things a bit better. – jim bob Jan 25 '18 at 14:03
  • I don't understand what the catch is here, do you want the method names to be the same as the options strings? You are already aware that command sends the selected option as string as an argument to its command. In which you can filter with if to run whichever methods based on that string. I don't understand your specific issue. – Nae Jan 25 '18 at 14:06
  • @Nae I'm not sure how to go about doing this: `In which you can filter with if to run whichever methods based on that string` – jim bob Jan 25 '18 at 14:08

2 Answers2

1

If you want to run specific methods for options, simply check the sent string and select the method based on the string using if / elif statements:

from tkinter import *


def xyz17():
    print('xyz17')
def abc27():
    print('abc27')
def qwe90():
    print('qwe90')
def uio19():
    print('uio19')
def jkl09():
    print('jkl09')
def zxc28():
    print('zxc28')

class Menu(OptionMenu):
    def __init__(self, master, status, *options):
        self.var = StringVar(master)
        self.var.set(status)
        OptionMenu.__init__(self, master, self.var, *options, command=self.option_handle)


    def option_handle(self, selected):
        # above specific case is simply print(selected) but
        if selected == "xyz17":
            xyz17()
        elif selected == "abc27":
            abc27()
        elif selected == "qwe90":
            qwe90()
        elif selected == "uio19":
            uio19()
        elif selected == "jkl09":
            jkl09()
        elif selected == "zxc28":
            zxc28()
        # if you specifically want to call methods that has exactly
        # the same name as options
        # eval(selected + "()")


def main():        
    TopFrame = Frame(root)
    TopFrame.pack()

    Menu1 = Menu(TopFrame, 'xyz', 'xyz17','abc27','qwe90')
    Menu2 = Menu(TopFrame, 'uio', 'uio19','jkl09','zxc28')

    Menu1.pack()
    Menu2.pack()

root = Tk()
main()
root.mainloop()
Nae
  • 14,209
  • 7
  • 52
  • 79
0

One way of running a command based on the option menu selection is to use a dictionary of functions: func_dict = {option: function, ...} and then pass the following function to the command option of the OptionMenu:

def func(value):
    func_dict[value]() 

to execute the function corresponding to the chosen option.

Here is an example:

from tkinter import *

options = ['xyz', 'xyz17', 'abc27', 'qwe90', 'uio', 'uio19', 'jkl09', 'zxc28']
func_dict = {option: lambda opt=option: print(opt) for option in options}

class Menu(OptionMenu):
    def __init__(self, master, status, *options):
        self.var = StringVar(master)
        self.var.set(status)
        OptionMenu.__init__(self, master, self.var, *options, command=self.func)

    def func(self, option):
        func_dict[option]()

def main():        
    topFrame = Frame(root)
    topFrame.pack()

    menu1 = Menu(topFrame, 'xyz', 'xyz17','abc27','qwe90')
    menu2 = Menu(topFrame, 'uio', 'uio19','jkl09','zxc28')

    menu1.pack()
    menu2.pack()

root = Tk()
main()
root.mainloop()
j_4321
  • 15,431
  • 3
  • 34
  • 61