简体   繁体   English

从 `main()` 创建的 `NSStatusItem` 没有显示在系统状态栏上

[英]`NSStatusItem` created from `main()` doesn't show up on system status bar

I'm trying to make a simple macOS Cocoa application using NSStatusItem to create a clickable icon on the system status bar.我正在尝试使用NSStatusItem创建一个简单的 macOS Cocoa 应用程序,以在系统状态栏上创建一个可点击的图标。 However, when I launch my application, I get this warning and the icon doesn't show up:但是,当我启动我的应用程序时,我收到此警告并且图标没有显示:

2020-03-03 14:43:11.564 Mocha_bug_example[936:39572] CGSGetActiveMenuBarDrawingStyle((CGSConnectionID)[NSApp contextID], &sCachedMenuBarDrawingStyle) returned error 268435459 on line 46 in NSStatusBarMenuBarDrawingStyle _NSStatusBarGetCachedMenuBarDrawingStyle(void)

Here's a minimal reproducible example for my application:这是我的应用程序的最小可重现示例:

#import <AppKit/AppKit.h>

NSStatusItem* statusItem;

int main (int argc, char* argv[]) {
        statusItem = [NSStatusBar.systemStatusBar statusItemWithLength: -1];
        statusItem.button.title = @"foobar";
        statusItem.visible = YES;

        [NSApplication.sharedApplication run];
        return 0;
}

I compiled and ran the example like this:我编译并运行了这样的例子:

MacBook-Air-5:Mocha ericreed$ clang -o Mocha_bug_example -framework AppKit -fobjc-arc Mocha_bug_example.m
MacBook-Air-5:Mocha ericreed$ ./Mocha_bug_example
2020-03-03 14:43:11.564 Mocha_bug_example[936:39572] CGSGetActiveMenuBarDrawingStyle((CGSConnectionID)[NSApp contextID], &sCachedMenuBarDrawingStyle) returned error 268435459 on line 46 in NSStatusBarMenuBarDrawingStyle _NSStatusBarGetCachedMenuBarDrawingStyle(void)
[Application hung until I pressed Ctrl+C]
^C
MacBook-Air-5:Mocha ericreed$ 

Note: disabling automatic reference counting and adding [statusItem release];注意:禁用自动引用计数并添加[statusItem release]; after calling run as this similar question suggested made no visible difference.在调用run因为这个类似的问题建议没有明显的区别。

#import <Cocoa/Cocoa.h>

int main(){
 NSAutoreleasePool *pool = [[NSAutoreleasePool alloc]init];
 NSApplication *application = [NSApplication sharedApplication];
 NSStatusItem* statusItem;
 statusItem = [NSStatusBar.systemStatusBar statusItemWithLength: -1];
 statusItem.button.title = @"foobar";
 statusItem.visible = YES;
 [application run];
 [pool drain];
 return 0;
}

Save file with the name 'statusBar_SO.m'保存名为“statusBar_SO.m”的文件

Compile from Terminal: clang statusBar_SO.m -framework Cocoa -o statusBar && ./statusBar从终端编译:clang statusBar_SO.m -framework Cocoa -o statusBar && ./statusBar

This is how to add status bar item to command line app mac osx cocoa这是如何将状态栏项目添加到命令行应用程序 mac osx cocoa

Adapting apodidae's answer to Swift.改编 apodidae 对 Swift 的回答。 Just put this in the main.swift file:只需将其放在 main.swift 文件中:

let app = NSApplication()
let statusItem = NSStatusBar.system.statusItem(withLength: -1)
statusItem.button!.title = "PENIS!"
app.run()

I don't understand the finer details of the NSReleasePool as apodidae included, but it works for me without that.我不了解 NSReleasePool 作为 apodidae 包含的更详细的细节,但没有它它对我有用。

This is not the kind of thing you can do in main() .这不是您可以在main()做的事情。

Except for extrememly unusual situations, you should never modify the main() that comes with the application template, and it must call NSApplicationMain() :除了不寻常的情况,你永远不应该修改应用程序模板附带的main() ,它必须调用NSApplicationMain()

int main(int argc, char *argv[])
{
    // start the application
    return NSApplicationMain(argc, (const char **) argv);
}

The Cocoa framework doesn't get initialized until you call NSApplicationMain() and is generally unusable until then. Cocoa 框架在您调用NSApplicationMain()之前不会被初始化,并且在此之前通常无法使用。

This kind of setup should be done in applicationWillFinishLaunching or applicationDidFinishLaunching .这种设置应该在applicationWillFinishLaunchingapplicationDidFinishLaunching

Update更新

The original poster is not using Xcode and is willing to brave the wilderness alone.原版海报使用Xcode,愿孤军奋战。 ;) ;)

This also implies that their application bundle will not have a main NIB file that would normally create and connect the application delegate object, main menu, and so forth.这也意味着他们的应用程序包将没有一个通常会创建和连接应用程序委托对象、主菜单等的主 NIB 文件。

There are intrepid individuals who have braved this territory and you can read about it in Creating a Cocoa application without NIB files .有一些勇敢的人勇敢地闯入了这个领域,您可以在创建没有 NIB 文件的 Cocoa 应用程序中了解它。

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

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