【问题标题】:Window called with "showWindow" not focused用“showWindow”调用的窗口没有聚焦
【发布时间】:2013-06-12 23:29:49
【问题描述】:

我有一个带有 Xcode 4.6.2 的简单 cocoa coredata 状态栏应用程序。情况是这样的:

MainMenu.xib 重命名为PreferencesWindow.xib,删除了主菜单,在窗口中创建了一个简单且有效的 coredata 函数,其中包含数组控制器和绑定。 我创建了一个新文件->用户界面->主菜单并将其命名为StatusBarMenu.xib。为其添加了一个简单的菜单并删除了主菜单。 创建新文件->objective-c 类->NSObject 的子类并将其命名为StatusBarController。 接口代码如下:

@property IBOutlet NSMenu *statusMenu;
@property NSStatusItem *statusItem;
@property [some items for statusbar image]

实现:

@synthesize [everything]
-(void)awakeFromNib{
    statusItem = [[NSStatusBar systemStatusBar]statusItemWithLength:NSVariableStatusItemLength];
    [some string, path and stuff for the images]
    statusItem.menu = statusMenu;
    statusItem.toolTip = @"";
    statusItem.highlightMode = YES;
}

然后我创建了另一个新文件->objective-c 类->NSWindowController 的子类,将其命名为 PreferencesWindowController 并保持原样。 然后是一个新的文件->objective-c 类->NSObjects 的子类,命名为 PreferencesAppController。这是.h的代码:

@property (assign) IBOutlet NSWindow *mainWindow;
@property (retain) PreferencesWindowController *prefController;
-(IBAction)showPreferences:(id)sender;

.m 代码:​​

@synthesize [everything];
-(IBAction)showPreferences:(id)sender{
    if(!self.prefController)
        self.prefController = [[PreferencesWindowController alloc] initWithWindowNibName:@"PreferencesWindow"];

    [self.prefController showWindow:sender];
}

AppDelegate 文件中只有 coredata 的代码,没有添加任何内容。 然后在PreferencesWindow.xib 中,我为PreferencesAppController 添加了NSObject(蓝色立方体),并带有一些绑定:Outlets-> mainWindow 使用简单的 coredata 函数绑定到窗口。 AppDelegate 将窗口出口绑定到同一个窗口,然后是引用出口-> 文件所有者委托,一些 saveactionmanagedobjectcontext。 在 StatusBarMenu.xib 中,我创建了一个 StatusBarController 对象并将其绑定到菜单 (outlets->statusMenu),创建了另一个名为 PreferencesAppController 的蓝色对象,并将 Received Actions->showPreferences 绑定到菜单项。

然后我运行程序,一切正常:状态栏中出现一个图标,下拉菜单有效,如果我点击“首选项...”,首选项窗口出现但...它没有聚焦!它位于其他窗口的顶部,但我必须单击以使其集中。 coredata 保存功能工作正常,除了我必须使用按钮手动保存,从状态栏菜单退出应用程序不会保存,但这是一个边缘问题。

为什么窗口没有聚焦?

【问题讨论】:

  • 这可能不是,但请确保您在 Info.plist 中使用的是 LSUIElement 而不是 LSBackgroundOnly。纯后台应用不应显示 UI。
  • 顺便说一下,请不要删除主菜单。文本编辑(例如,剪切、复制和粘贴)、关闭窗口、退出应用程序等菜单项都在其中。 ⌘Z、⌘C、⌘W 和 ⌘Q 等标准快捷键在删除后将无法使用。
  • 是的,在 info.plist 中我添加了“应用程序是代理 (UIElement)”来充当状态栏应用程序。故意阻止使用快捷方式。状态栏中只有一个退出菜单项。但是,如果应用程序在后台运行,是否只有选择了首选项面板才能使用快捷方式?
  • 是的,如果您的面板是按键或您从应用程序中显示的任何其他窗口/面板是按键,那么即使您没有,您的菜单(在您的主菜单中)也会用于按键组合分辨率拥有菜单栏。这包括对话框,因此如果您的应用需要,例如,要求为某些服务输入密码,用户可能希望能够粘贴他们的密码。
  • 非常有用的信息,谢谢

标签: objective-c cocoa focus showwindow


【解决方案1】:

根据您对应用程序的描述,我假设它是“状态栏应用程序”,旨在在后台运行,而不是显示在 Dock 中。

这意味着您的应用程序不是活动应用程序。用户单击您的状态项并从其菜单中选择一项不会改变这一点。

当一个不是活动应用程序的应用程序打开一个窗口时,该窗口不会获得焦点(因为这通常相当于从用户在 正在的应用程序中所做的任何事情中窃取焦点活跃)。

所以,你需要activate your application

【讨论】:

  • [NSApp activateIgnoringOtherApps:YES] 不起作用。但是,OrderFrontStandardAboutPanel 运行良好:作为首选项窗口在所有内容之上,但最终集中。
  • 一点提示:在我尝试使用 activateIgnoringOtherApps 之前,关于面板运行良好:它根本不会影响对应用程序行为的任何更改。
  • 问题解决了!我将 [NSApp activateIgnoringOtherApps:YES] 放在错误的控制器中(状态栏控制器而不是首选项应用控制器)。现在它工作正常!非常感谢。现在我只需要了解如何在 coredata 中自动保存首选项窗口的内容,而不是手动按下按钮。
  • 有什么方法可以强制NSWindow 在出现时显示其菜单?现在我必须来回切换应用程序才能显示菜单。
猜你喜欢
  • 1970-01-01
  • 2011-06-05
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多