如何从Tkinter应用程序菜单单击中打开文件?

时间:2019-08-22 16:24:05

标签: python windows tkinter

我已经为菜单编程,当前单击菜单项时,它会执行print(sometext from menu)

我需要此菜单单击选项来打开python文件,而不是打印文件名。

这似乎是一个非常简单的问题,但是我是python的新手,并且仍然在学习。

我无法找到适合这种情况的信息。我试过popenexecfile都没有运气。尽管我不确定我是否正确使用了它们。

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()

我希望它通过执行“ ecclesiastes.py”和“ ecclesiasticus.exe”的几种不同方法来打开,但是不幸的是,错误消息只告诉我我不知道自己被卡住了什么而不是关于如何获取执行这两个文件所需的正确代码的线索。我在popen文件前放置了.py,在execfile文件前放置了.exe,但是我认为这样做不正确。

我在两个文件名中的每个文件名前放置了print,以便此处的其他人指出正确的命令,因为我认为execfilepopen对于此代码不正确。

2 个答案:

答案 0 :(得分:1)

stovfl的评论是一个很好的解决方案。

我经常使用:

  

os.startfile('文件名')

我不能告诉你这是否是最好的选择,但是它可以工作:)

您的代码如下:

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()

我希望这能解决您的问题!

答案 1 :(得分:1)

由于它似乎是您实际要执行的文件,因此可以执行以下操作:

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()