应用程序启动时显示NSPopover

时间:2014-07-30 09:37:26

标签: objective-c pyobjc nsstatusitem nspopover

我正在使用Pyobjc来创建NSStatusItem。单击它时,我显示的是NSPopOver。这工作正常。但是,我的要求是在应用程序启动时立即显示弹出框,而不会由用户执行任何操作。直接在finishLaunching中调用回调不起作用。有没有办法实现这个目标?即使可以模拟NSStatusView上的点击,它也会足够好。

class TestApp(NSApplication):

    def finishLaunching(self):
        # Make statusbar item
        statusbar = NSStatusBar.systemStatusBar()
        self.statusitem = statusbar.statusItemWithLength_(NSVariableStatusItemLength)
        self.statusitem.setTarget_(self)
        self.statusitem.setAction_('statusItemClicked:')
        self.icon = NSImage.alloc().initByReferencingFile_('app-icon.png')
        self.icon.setScalesWhenResized_(True)
        self.icon.setSize_((20, 20))
        self.statusitem.setImage_(self.icon)
        self.statusitem.setHighlightMode_(1)

        # self.statusItemClicked_(None)

    def statusItemClicked_(self, notification):
        self.viewController = SimpleXibDemoController.alloc().initWithWindowNibName_("Login")

        # Show the window
        self.viewController.showWindow_(self.viewController)
        rect = self.statusitem.valueForKey_('button').frame()
        self.viewController.popover.showRelativeToRect_ofView_preferredEdge_(rect, self.statusitem.valueForKey_('button'), NSMaxYEdge)

2 个答案:

答案 0 :(得分:2)

我终于得到了一个有点粗略的解决方案。我有一个方法可以像这样定位弹出窗口:

- (IBAction)showPopover:(id)sender {
    [popover showRelativeToRect:self.statusItemView.bounds ofView:self.statusItemView preferredEdge:NSMinYEdge];
}

在你的案例中的applicationDidFinishLaunching或finishLaunching中,我没有直接调用方法,而是使用performSelector调用它:

[self performSelector:@selector(showPopover:) withObject:self afterDelay:0];

即使将延迟设置为0也有效,我不知道为什么,现在它正确定位了弹出窗口。

编辑:这似乎只是在情境上起作用。即使通过创建一个视图控制器并从viewDidAppear调用它,弹出窗口只会被定位一半的时间。

编辑2:我在状态项的窗口中添加了一个窗口控制器,并覆盖了windowDidLoad。然而事实证明,在我甚至可以设置控制器窗口之前加载窗口,因此不会调用windowDidLoad。

答案 1 :(得分:1)

您必须等到视图显示NSPopover。覆盖NSViewController子类中的viewDidAppear并将其显示在那里。 (如果您的最低部署目标小于OS X Yosemite,则覆盖loadView。)