侦听带有菜单的NSStatusItem上的操作

问题描述

我有一个带有菜单NsstatusItem。如何在不丢失菜单的情况下从状态项获取鼠标/触摸事件?我当时在考虑某种解决方法,可以参加活动并手动弹出菜单,但我不确定可行性。

下面的示例演示了该问题。与该示例和我的实际代码唯一的不同是我正在使用菜单委托。

#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

解决方法

此解决方案来自上一个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;
}

,

如果替换main.m并删除info.plist中的MainMenu笔尖(使用ARC),则这种无笔尖的编程方法将在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;
}

相关问答

Selenium Web驱动程序和Java。元素在(x,y)点处不可单击。其...
Python-如何使用点“。” 访问字典成员?
Java 字符串是不可变的。到底是什么意思?
Java中的“ final”关键字如何工作?(我仍然可以修改对象。...
“loop:”在Java代码中。这是什么,为什么要编译?
java.lang.ClassNotFoundException:sun.jdbc.odbc.JdbcOdbc...