从状态项菜单项启动的NSWindow不显示为活动窗口

0 投票
2 回答
1421 浏览
提问于 2025-04-11 09:27

我有一个用PyObjC写的状态项应用程序。这个状态项有一个菜单项,点击后应该会打开一个新窗口:

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

Preferences是一个NSWindowController类:

class Preferences(NSWindowController):

当我在XCode中运行这个应用程序(点击构建和运行)时,一切正常。但是,当我从XCode外部直接运行生成的.app文件时,状态项和菜单项都正常显示,但当我点击“Preferences”菜单项时,窗口却不出现。我通过查看控制台输出确认了launchPreferences代码确实在运行。

而且,如果我再次双击.app文件,窗口会出现,但如果我点击其他窗口,比如Finder窗口,偏好设置窗口就会消失。这让我觉得这可能和当前活动窗口有关。

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

preferences.makeKeyAndOrderFront_()

或者

preferences.setLevel_(NSNormalWindowLevel)

那么我就会收到一个错误:

'Preferences'对象没有这个属性

2 个回答

1

我对PyObjC一点都不了解,也没用过。不过如果这是Objective-C的代码,我会说如果你想让窗口成为最前面的窗口,就应该在窗口对象上调用makeKeyAndOrderFront这个方法。新创建的窗口默认既不是关键窗口,也不是前景窗口,除非你像这种情况一样,把它设置成这两者。

还有一个让我担心的问题是,你提到窗口在不活跃时会消失(变得不可见)。这听起来像是你的窗口并不是真正的窗口。你是不是不小心在Interface Builder里把它设置成了“工具窗口”?能不能试着在窗口第一次显示之前,手动把窗口的级别设置为NSNormalWindowLevel,看看它在变得不活跃时是否还会消失?

5

你需要给应用发送一个叫做 activateIgnoringOtherApps: 的消息,然后再发送一个让窗口变为主窗口并显示在前面的消息 makeKeyAndOrderFront:。

在Objective-C中,这样写:

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

撰写回答