从statusItem menuItem启动的NSWindow不会显示为活动窗口

时间:2020-03-06 14:54:54  来源:igfitidea点击:

我有一个用PyObjC编写的statusItem应用程序。 statusItem具有一个menuItem,当单击该菜单项时应该会启动一个新窗口:

# Create statusItem
statusItem = NSStatusBar.systemStatusBar().statusItemWithLength_(NSVariableStatusItemLength)
statusItem.setHighlightMode_(TRUE)
statusItem.setEnabled_(TRUE)
statusItem.retain()

# Create menuItem
menu = NSMenu.alloc().init()
menuitem = NSMenuItem.alloc().initWithTitle_action_keyEquivalent_('Preferences', 'launchPreferences:', '')
menu.addItem_(menuitem)
statusItem.setMenu_(menu)

launchPreferences:方法是:

def launchPreferences_(self, notification):
    preferences = Preferences.alloc().initWithWindowNibName_('Preferences')
    preferences.showWindow_(self)

首选项是一个NSWindowController类:

class Preferences(NSWindowController):

当我在XCode(Build&Go)中运行应用程序时,这可以正常工作。但是,当我从XCode外部运行生成的.app文件时,statusItem和menuItem会按预期显示,但是当我单击"首选项" menuItem时,不会出现该窗口。我已经通过检查控制台输出来验证launchPreferences代码是否正在运行。

此外,如果我再次双击.app文件,则会显示该窗口,但是如果我通过单击(例如)在Finder窗口上将活动窗口移开,则首选项窗口将消失。在我看来,这与活动窗口有关。

更新1
我已经尝试了这两个答案,但都没有用。如果我添加到launchPreferences方法中:

preferences.makeKeyAndOrderFront_()

或者

preferences.setLevel_(NSNormalWindowLevel)

然后我得到一个错误:

'Preferences' object has no attribute

解决方案

我们需要向应用程序发送ActivateIgnoringOtherApps:消息,然后发送窗口makeKeyAndOrderFront:。

在Objective-C中,这将是:

[NSApp activateIgnoringOtherApps:YES];
[[self window] makeKeyAndOrderFront:self];

我不知道PyObjC,从未使用过它,但是如果这是Objective-C代码,我想说如果我们希望它成为第一个前窗口,则应该在窗口对象上调用makeKeyAndOrderFront:。新创建的窗口既不是键,也不是前部,除非我们在此情况下选择两者之一或者两者兼而有之。

令我担心的另一个问题是,我们说窗口不再活动时,它就会消失(变得不可见)。听起来窗口不是真实的窗口。我们是否不小心将其设置为Interface Builder中的"实用程序窗口"?我们是否可以尝试在将窗口第一次显示在屏幕上之前使用setLevel:设置为NSNormalWindowLevel来手动设置窗口级别,当窗口变为非活动状态时窗口是否仍然消失?