Skip to main content
  1. About
  2. For Teams
Asked
Viewed 2k times
0

I have programmed a menu and currently when a menu item is clicked it does a print(sometext from menu).

I need this menu click option to open a python file instead of printing the name of the file.

This seems like a very simple issue but I am new to python and am still learning.

I cannot find an exact fit to this circumstance. I have tried popen and execfile with no luck.; though I am not sure if I used them correctly.

import tkinter

def set_menu(window, choices):
    menubar = tkinter.Menu(root)
    window.config(menu=menubar)

    def _set_choices(menu, choices):
        for label, command in choices.items():
            if isinstance(command, dict):
                # Submenu
                submenu = tkinter.Menu(menu)
                menu.add_cascade(label=label, menu=submenu)
                _set_choices(submenu, command)
            elif label == '-' and command == '-':
                # Separator
                menu.add_separator()
            else:
                # Simple choice
                menu.add_command(label=label, command=command)

    _set_choices(menubar, choices)


if __name__ == '__main__':
    import sys

    root = tkinter.Tk()

    from collections import OrderedDict

    set_menu(root, {
        'Table of Contents': OrderedDict([
            ('Ecclesiastes', lambda: print('Ecclesiastes.py')),
            ('Ecclesiasticus', lambda: print('ecclesiaticus.exe')),
            ('-', '-'),
            ('Quit', lambda: sys.exit(0))
        ])
    })
    root.mainloop()

I expected it to open by doing a few different methods of executing the 'ecclesiastes.py' and the 'ecclesiasticus.exe' but unfortunately the error messages really only tell me I have no idea what i am stuck on rather than a clue as to how to get the proper code needed to execute these two files. I put popen before the .py file and execfile before the .exe file but I think that is not near the correct way to do this.

I placed print before each of the two file names so that the correct command can be pointed out by someone else here because I do not think execfile or popen are correct for this code.

1

2 Answers 2

2

Since it appears the you actually want to execute the file, you could do it something like this:

import os
import shlex
import subprocess
import sys
import tkinter


def set_menu(window, choices):
    menubar = tkinter.Menu(root)
    window.config(menu=menubar)

    def _set_choices(menu, choices):
        for label, command in choices.items():
            if isinstance(command, dict):
                # Submenu
                submenu = tkinter.Menu(menu)
                menu.add_cascade(label=label, menu=submenu)
                _set_choices(submenu, command)
            elif label == '-' and command == '-':
                # Separator
                menu.add_separator()
            else:
                # Simple choice
                menu.add_command(label=label, command=command)

    _set_choices(menubar, choices)

def exec_command(command):
    cmd = shlex.split(command)
    print('subprocess({})'.format(cmd))
    subprocess.run(cmd, shell=True)


if __name__ == '__main__':
    from collections import OrderedDict
    import sys

    root = tkinter.Tk()

    set_menu(root, {'Table of Contents':
                        OrderedDict([
                            ('Ecclesiastes',
                                lambda: exec_command('Ecclesiastes.py')),
                            ('Ecclesiasticus',
                                lambda: exec_command('ecclesiaticus.exe -arg 42')),
                            ('-', '-'),
                            ('Quit', 
                                lambda: sys.exit(0))
                        ])
                   })
    root.mainloop()
Sign up to request clarification or add additional context in comments.

Comments

1

The comment of stovfl is a great solution.

I often use:

os.startfile('filename')

I can't tell you if this the best option out there but it works :)

Your code would look like this:

import tkinter 
import os

def set_menu(window, choices):
    menubar = tkinter.Menu(root)
    window.config(menu=menubar)

    def _set_choices(menu, choices):
        for label, command in choices.items():
            if isinstance(command, dict):
                # Submenu
                submenu = tkinter.Menu(menu)
                menu.add_cascade(label=label, menu=submenu)
                _set_choices(submenu, command)
            elif label == '-' and command == '-':
                # Separator
                menu.add_separator()
            else:
                # Simple choice
                menu.add_command(label=label, command=command)

    _set_choices(menubar, choices)


if __name__ == '__main__':
    import sys

    root = tkinter.Tk()

    from collections import OrderedDict

    set_menu(root, {
        'Table of Contents': OrderedDict([
            ('Ecclesiastes', lambda: os.startfile('Ecclesiastes.py')),
            ('Ecclesiasticus', lambda: os.startfile('ecclesiaticus.exe')),
            ('-', '-'),
            ('Quit', lambda: sys.exit(0))
        ])
    })
    root.mainloop()

I hope this solves your question!

Comments

Your Answer

Post as a guest

Required, but never shown

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.

Morty Proxy This is a proxified and sanitized view of the page, visit original site.