简体   繁体   English

应用程序启动时显示NSPopover

[英]Show NSPopover when the application starts

I am using Pyobjc to create a NSStatusItem. 我正在使用Pyobjc来创建NSStatusItem。 When it is clicked, I am showing an NSPopOver. 单击它时,我显示的是NSPopOver。 This is working fine. 这工作正常。 However, my requirement is to show the popover as soon as the application starts without any action by the user. 但是,我的要求是在应用程序启动时立即显示弹出框,而不会由用户执行任何操作。 Calling the callback directly in finishLaunching is not working. 直接在finishLaunching中调用回调不起作用。 Is there any way to achieve this? 有没有办法实现这个目标? It will be good enough even if can just simulate the click on NSStatusView. 即使可以模拟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)

I finally got a somewhat sketchy solution. 我终于得到了一个有点粗略的解决方案。 I have a method which positions the popover like so: 我有一个定位popover的方法,如下所示:

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

In applicationDidFinishLaunching, or finishLaunching in your case, instead of calling the method directly I called it with performSelector instead: 在您的情况下的applicationDidFinishLaunching或finishLaunching中,我没有直接调用该方法,而是使用performSelector调用它:

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

Even setting the delay to 0 works, which I do not know why, and it now positions the popover correctly. 甚至将延迟设置为0也起作用,我不知道为什么,现在它正确定位了弹出窗口。

Edit: This seems to only work situationally. 编辑:这似乎只是在情境上工作。 Even by creating a view controller and calling it from viewDidAppear, the popover only gets positioned half of the time. 即使通过创建一个视图控制器并从viewDidAppear调用它,弹出窗口只会定位一半的时间。

Edit 2: I added a window controller to the status item's window, and overrode windowDidLoad. 编辑2:我在状态项的窗口中添加了一个窗口控制器,并覆盖了windowDidLoad。 However as it turned out, the window is loaded before I can even set the controller's window so windowDidLoad is not called. 然而事实证明,在我甚至可以设置控制器的窗口之前加载窗口,因此不会调用windowDidLoad。

You have to wait until the view appears to present the NSPopover . 您必须等到视图出现NSPopover Override viewDidAppear in your NSViewController subclass and present it there. 覆盖NSViewController子类中的viewDidAppear并将其呈现在那里。 (Or override loadView if your minimum deployment target is less than OS X Yosemite.) (或者,如果最小部署目标小于OS X Yosemite,则覆盖loadView 。)

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM