从statusItem menuItem启动的NSWindow不会显示为活动窗口
我有一个用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来手动设置窗口级别,当窗口变为非活动状态时窗口是否仍然消失?