有没有办法在 Mac 上的应用程序 window 中显示菜单栏?

Is there a way to show the menu bar inside an application window on a Mac?

我正在关注一个 tutorial 并且在完全按照所说的去做时收到了不同的结果。

我希望菜单栏显示在实际的 tkinter 应用程序中 window 就像教程中那样。他正在使用 Windows。它而是显示在计算机的实际顶部菜单栏上。如果这有所作为,我正在使用 Mac。有办法解决这个问题吗?

这是我的代码:

from tkinter import *


def doNothing():
    label1 = Label(root, text="Doing nothing")
    label1.pack()

root = Tk()

mainmenu = Menu(root)
root.config(menu=mainmenu)

filemenu = Menu(mainmenu)
mainmenu.add_cascade(label="File", menu=filemenu)
filemenu.add_command(label="New Project", command=doNothing)
filemenu.add_command(label="New", command=doNothing)
filemenu.add_separator()
filemenu.add_command(label="Exit", command=doNothing)

editmenu=Menu(mainmenu)
mainmenu.add_cascade(label="Edit", menu=editmenu)
editmenu.add_command(label="Redo", command=doNothing)


root.mainloop()

I am using a Mac if that makes a difference. Is there a way to fix this?

是的,这很重要。 Tk 仍然不支持样式菜单。根据 TkDocs:

You'll notice on some recent Linux distributions that many applications show their menus at the top of the screen when active, rather than in the window itself. Tk does not yet support this style of menus.

更多详情...

下面还写着:

On Mac OS X though, there is a single menubar along the top of the screen, shared by each window. As far as your Tk program is concerned, each window still does have its own menubar; as you switch between windows, Tk will automatically take care of making sure that the correct menubar is displayed at the top of the screen. If you don't specify a menubar for a particular window, Tk will use the menubar associated with the root window; you'll have noticed by now that this is automatically created for you when your Tk application starts.

然后它给了我们一个 提示:

Because on Mac OS X all windows have a menubar, it's important to make sure you do define one, either for each window or a fallback menubar for the root window. Otherwise, you'll end up with the "built-in" menubar, which contains menus that are only intended for use when typing commands directly into the interpreter.

此外,this issue says

The Tk menu command is hooked into the Mac OS X global menubar. If you want a menu without using the global menubar, you will have to write your own top level menu.

并且 here 的人询问如何删除顶部的菜单,以防您有兴趣在 window 本身上实现您的菜单:

The name that shows up in the menu is derived by OS X from the application name in the executing application bundle. If you don't package your program up as an OS X application bundle, defaults will be used; in the case of Python OS X framework builds, Python provides a Python.app within the framework to allow the Python process to be automatically promoted to a full OS X GUI process.
Probably the simplest approach is to use py2app to create a double-clickable app with the name you want. There's an example in an answer to a similar question on Whosebug. And there are some old but still relevant details documented in the Tcl/TkAqua FAQ.

一般来说,根据 this article

On the Macintosh, whenever the toplevel is in front, this menu's cascade items will appear in the menubar across the top of the main monitor. On Windows and Unix, this menu's items will be displayed in a menubar accross the top of the window. These menus will behave according to the interface guidelines of their platforms

...

As noted, menubars may behave differently on different platforms. One example of this concerns the handling of checkbuttons and radiobuttons within the menu. While it is permitted to put these menu elements on menubars, they may not be drawn with indicators on some platforms, due to system restrictions.

其他可能有用的文章

不,这是不可能的。至少,不像其他操作系统上的菜单栏那样工作。

您可以使用带有菜单按钮的框架来制作菜单,并将其放在 window 的顶部。它与本机菜单栏的工作方式不太一样,屏幕顶部仍然有一个几乎是空的菜单。