使用菜单监听 NSStatusItem 上的操作
Listen for Actions on a NSStatusItem With a Menu
我有一个附有菜单的 NSStatusItem
。如何在不丢失菜单的情况下从状态项获取 mouse/touch 事件?我在想也许是某种解决方法,我可以接收事件并手动弹出菜单,但我不确定可行性。
下面的例子演示了这个问题。这个例子和我的实际代码的唯一主要区别是我使用的是菜单委托。
#import <Cocoa/Cocoa.h>
@interface AppDelegate : NSObject <NSApplicationDelegate> {
IBOutlet NSWindow *window;
NSStatusItem* statusItem;
NSMenu* statusMenu;
NSMenuItem* menuItem;
}
-(IBAction)stuffHappened:(id)sender;
@end
@implementation AppDelegate
-(void)awakeFromNib{
statusItem = [[NSStatusBar systemStatusBar] statusItemWithLength:NSSquareStatusItemLength];
statusMenu = [[NSMenu alloc] initWithTitle:@""];
menuItem = [[NSMenuItem alloc] initWithTitle:@"test"
action:nil
keyEquivalent:@""];
statusItem.button.title = @"\U0001F410";
[statusItem setMenu:statusMenu]; //commenting out this line allows the action to fire
[statusMenu addItem:menuItem];
[[statusItem button] setTarget:self];
statusItem.button.action = @selector(stuffHappened:);
}
-(IBAction)stuffHappened:(id)sender {
NSLog(@"Stuff happened");
}
@end
如果您替换 main.m 并删除 info.plist 中的 MainMenu nib(使用 ARC),此 nib-less 编程方法将在 Xcode 中 运行:
#import <Cocoa/Cocoa.h>
@interface AppDelegate : NSObject <NSApplicationDelegate> {
NSStatusItem* statusItem;
NSMenuItem* menuItem;
}
-(void)stuffHappened:(id)sender;
@end
@implementation AppDelegate
//-(void)awakeFromNib{
- (void) applicationDidFinishLaunching:(NSNotification *)notification {
NSMenu *menu = [[NSMenu alloc] init];
statusItem = [[NSStatusBar systemStatusBar] statusItemWithLength:60];
statusItem.button.title = @"foobar";
[statusItem setMenu:menu];
menuItem = [menu addItemWithTitle:@"Item 1" action:@selector(stuffHappened:) keyEquivalent:@""];
[menuItem setTarget:self];
menuItem = [menu addItemWithTitle:@"Item 2" action:@selector(stuffHappened:) keyEquivalent:@""];
[menuItem setTarget:self];
[menu addItem:[NSMenuItem separatorItem]];
menuItem = [menu addItemWithTitle:@"Quit" action:@selector(terminate:) keyEquivalent:@""];
}
-(void)stuffHappened:(id)sender {
NSLog(@"Stuff happened : %@",sender);
}
@end
int main(){
NSApplication *application = [NSApplication sharedApplication];
[application setActivationPolicy:NSApplicationActivationPolicyRegular];
AppDelegate *appDelegate = [[AppDelegate alloc] init];
[application setDelegate:appDelegate];
[application activateIgnoringOtherApps:YES];
[application run];
return 0;
}
这个解决方案来自之前的 SO 问题:Highlighting NSStatusItem with attributed string
并可能做你想做的事。不幸的是,popUpStatusItemMenu 现已弃用。
#import <Cocoa/Cocoa.h>
@interface AppDelegate : NSObject <NSApplicationDelegate> {
NSStatusItem* statusItem;
NSMenu* statusMenu;
NSMenuItem* menuItem;
}
-(void)statusItemHandler:(id)sender;
-(void)menuHandler:(id)sender;
@end
@implementation AppDelegate
-(void)menuHandler:(id)sender {
NSLog(@"Menu item = %@",sender);
}
-(void)statusItemHandler:(id)sender {
NSLog(@"StatusItem hit.");
statusMenu = [[NSMenu alloc] init];
menuItem = [statusMenu addItemWithTitle: @"Item 1" action:@selector(menuHandler:) keyEquivalent:@""];
menuItem = [statusMenu addItemWithTitle: @"Item 2" action:@selector(menuHandler:) keyEquivalent:@""];
[statusMenu addItem:[NSMenuItem separatorItem]];
menuItem = [statusMenu addItemWithTitle:@"Quit" action:@selector(terminate:) keyEquivalent:@""];
[statusItem popUpStatusItemMenu:statusMenu];
}
-(void)applicationDidFinishLaunching:(NSNotification *)notification {
statusItem = [[NSStatusBar systemStatusBar] statusItemWithLength:NSSquareStatusItemLength];
statusItem.button.title = @"\U0001F410";
statusItem.button.action = @selector(statusItemHandler:);
}
@end
int main(){
NSApplication *application = [NSApplication sharedApplication];
[application setActivationPolicy:NSApplicationActivationPolicyRegular];
AppDelegate *appDelegate = [[AppDelegate alloc] init];
[application setDelegate:appDelegate];
[application activateIgnoringOtherApps:YES];
[application run];
return 0;
}
我有一个附有菜单的 NSStatusItem
。如何在不丢失菜单的情况下从状态项获取 mouse/touch 事件?我在想也许是某种解决方法,我可以接收事件并手动弹出菜单,但我不确定可行性。
下面的例子演示了这个问题。这个例子和我的实际代码的唯一主要区别是我使用的是菜单委托。
#import <Cocoa/Cocoa.h>
@interface AppDelegate : NSObject <NSApplicationDelegate> {
IBOutlet NSWindow *window;
NSStatusItem* statusItem;
NSMenu* statusMenu;
NSMenuItem* menuItem;
}
-(IBAction)stuffHappened:(id)sender;
@end
@implementation AppDelegate
-(void)awakeFromNib{
statusItem = [[NSStatusBar systemStatusBar] statusItemWithLength:NSSquareStatusItemLength];
statusMenu = [[NSMenu alloc] initWithTitle:@""];
menuItem = [[NSMenuItem alloc] initWithTitle:@"test"
action:nil
keyEquivalent:@""];
statusItem.button.title = @"\U0001F410";
[statusItem setMenu:statusMenu]; //commenting out this line allows the action to fire
[statusMenu addItem:menuItem];
[[statusItem button] setTarget:self];
statusItem.button.action = @selector(stuffHappened:);
}
-(IBAction)stuffHappened:(id)sender {
NSLog(@"Stuff happened");
}
@end
如果您替换 main.m 并删除 info.plist 中的 MainMenu nib(使用 ARC),此 nib-less 编程方法将在 Xcode 中 运行:
#import <Cocoa/Cocoa.h>
@interface AppDelegate : NSObject <NSApplicationDelegate> {
NSStatusItem* statusItem;
NSMenuItem* menuItem;
}
-(void)stuffHappened:(id)sender;
@end
@implementation AppDelegate
//-(void)awakeFromNib{
- (void) applicationDidFinishLaunching:(NSNotification *)notification {
NSMenu *menu = [[NSMenu alloc] init];
statusItem = [[NSStatusBar systemStatusBar] statusItemWithLength:60];
statusItem.button.title = @"foobar";
[statusItem setMenu:menu];
menuItem = [menu addItemWithTitle:@"Item 1" action:@selector(stuffHappened:) keyEquivalent:@""];
[menuItem setTarget:self];
menuItem = [menu addItemWithTitle:@"Item 2" action:@selector(stuffHappened:) keyEquivalent:@""];
[menuItem setTarget:self];
[menu addItem:[NSMenuItem separatorItem]];
menuItem = [menu addItemWithTitle:@"Quit" action:@selector(terminate:) keyEquivalent:@""];
}
-(void)stuffHappened:(id)sender {
NSLog(@"Stuff happened : %@",sender);
}
@end
int main(){
NSApplication *application = [NSApplication sharedApplication];
[application setActivationPolicy:NSApplicationActivationPolicyRegular];
AppDelegate *appDelegate = [[AppDelegate alloc] init];
[application setDelegate:appDelegate];
[application activateIgnoringOtherApps:YES];
[application run];
return 0;
}
这个解决方案来自之前的 SO 问题:Highlighting NSStatusItem with attributed string 并可能做你想做的事。不幸的是,popUpStatusItemMenu 现已弃用。
#import <Cocoa/Cocoa.h>
@interface AppDelegate : NSObject <NSApplicationDelegate> {
NSStatusItem* statusItem;
NSMenu* statusMenu;
NSMenuItem* menuItem;
}
-(void)statusItemHandler:(id)sender;
-(void)menuHandler:(id)sender;
@end
@implementation AppDelegate
-(void)menuHandler:(id)sender {
NSLog(@"Menu item = %@",sender);
}
-(void)statusItemHandler:(id)sender {
NSLog(@"StatusItem hit.");
statusMenu = [[NSMenu alloc] init];
menuItem = [statusMenu addItemWithTitle: @"Item 1" action:@selector(menuHandler:) keyEquivalent:@""];
menuItem = [statusMenu addItemWithTitle: @"Item 2" action:@selector(menuHandler:) keyEquivalent:@""];
[statusMenu addItem:[NSMenuItem separatorItem]];
menuItem = [statusMenu addItemWithTitle:@"Quit" action:@selector(terminate:) keyEquivalent:@""];
[statusItem popUpStatusItemMenu:statusMenu];
}
-(void)applicationDidFinishLaunching:(NSNotification *)notification {
statusItem = [[NSStatusBar systemStatusBar] statusItemWithLength:NSSquareStatusItemLength];
statusItem.button.title = @"\U0001F410";
statusItem.button.action = @selector(statusItemHandler:);
}
@end
int main(){
NSApplication *application = [NSApplication sharedApplication];
[application setActivationPolicy:NSApplicationActivationPolicyRegular];
AppDelegate *appDelegate = [[AppDelegate alloc] init];
[application setDelegate:appDelegate];
[application activateIgnoringOtherApps:YES];
[application run];
return 0;
}