我正在使用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)
答案 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
。)