【问题标题】:How to open a file from a tkinter app menu click?如何从 tkinter 应用程序菜单单击打开文件?
【发布时间】:2019-08-22 16:24:05
【问题描述】:

我已经编写了一个菜单,目前当单击一个菜单项时,它会执行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 不适合此代码。

【问题讨论】:

标签: python windows tkinter


【解决方案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()

【讨论】:

    【解决方案2】:

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

    希望这能解决你的问题!

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2021-09-22
      • 1970-01-01
      • 2012-10-22
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2017-11-09
      相关资源
      最近更新 更多