如何在没有打开窗口的情况下更改wxPython中的OSX菜单栏?
我正在写一个wxPython应用程序,这个程序在关闭所有窗口后仍然保持打开状态,这样你就可以把新文件拖放到OSX的图标上(我用的是myApp.SetExitOnFrameDelete(False)
)。
不过,如果我关闭了所有窗口,OSX的菜单栏只会显示一个“帮助”菜单。我想至少添加一个文件/打开的菜单项,或者保持主窗口的菜单栏。请问在wxPython中有办法做到这一点吗?
其实,我也愿意接受一些非wxPython的解决办法(比如在pyobjc中设置菜单,但其余的界面用wxPython来做)。在OSX上开发wxPython本来就很麻烦;)
更新:我通过Lyndsey Ferguson的建议解决了这个问题。以下是我所做的:
- 在启动时,我创建一个窗口,然后立即将其隐藏。我把它的位置设置为
(-10000,-10000)
,这样它就不会在屏幕上闪烁(哎,这真是个脏招!) - 我在这个窗口中创建了一个空的EVT_CLOSE事件处理器,这样它就无法被关闭。
- 似乎销毁一个窗口会重置OSX的菜单,但隐藏窗口不会……所以当最后一个窗口关闭时,我需要再次显示并隐藏这个窗口(隐藏是必要的,这样用户就不能通过窗口菜单或Cmd-`切换到这个窗口)。
是的,这真的很丑陋……如果有人能想出一个更好的解决办法,我会非常感激。
更新 2:其实可以用更简单的方法解决:如果我们不关闭最后一个窗口,只需隐藏它,并确保它不再响应菜单事件。
2 个回答
现在你可以使用 wx.MenuBar.MacSetCommonMenuBar()
来设置一个菜单栏(你需要先创建这个菜单栏),这个菜单栏会在没有打开任何窗口时使用。
如果你只是想要一个默认的 macOS 菜单栏(里面已经有应用程序和窗口菜单),那么下面这段代码就是最简单的了:
menubar = wx.MenuBar()
wx.MenuBar.MacSetCommonMenuBar(menubar)
这样一来,你的应用程序也能直接响应 Command+Q 的快捷键。
在这里,wx.MenuItem
的 ID wx.ID_ABOUT
和 wx.ID_EXIT
是特别的,因为 这些 ID 的菜单项会被移动到 macOS 的应用程序菜单中。文档中实际上把应用程序菜单称为“苹果”菜单(比如在 这个 wx.MenuBar.OSXGetAppleMenu()
函数的文档中提到的菜单就是应用程序菜单),这可能是出于历史原因。
你能不能创建一个在屏幕外的隐藏窗口?这有点像小技巧,不过我记得为了让我的基于wxPython的应用在Mac OS X上正常工作,我做了很多这样的技巧。
注意:你需要禁用关闭按钮,并设置这个隐藏窗口,让它不出现在窗口菜单里。
顺便说一下:你有没有考虑把你的Python应用的图形界面部分分离出来,使用PyObjC在Mac OS X上开发?这样你会得到更多本地化的行为...