【问题标题】:Cocoa: Right Click NSStatusItem可可:右键单击 NSStatusItem
【发布时间】:2010-12-30 19:59:46
【问题描述】:

我是一个 .Net 开发人员,需要将一个小项目移植到 Mac 中,所以我对 Objective C 几乎一无所知。事实上,下面的代码只是一堆抓着稻草在黑暗中射击的东西。

尝试构建一个状态菜单程序,根据是左键单击还是右键单击/ctrl+单击来打开一个或另一个窗口。这是我所拥有的,它仅适用于左键单击(显然):

-(void) awakeFromNib{

    NSBundle *bundle = [NSbundle mainBundle];

    statusItem = [[NSStatusBar systemStatusBar] statusItemWithLength:NSSquareStatusItemLength] retain];
    [statusImage = [[NSImage alloc] initWithContentsOfFile:[bundle pathForResource:@"icon" ofType:@"png"]];
    [statusItem setImage:statusImage];
    [statusItem setToolTip:@"Program Name"];
    [statusItem setHighlightMode:YES];
    [statusItem setAction:@selector(openWin:)];
    [statusItem setTarget: self];
}

-(void)openWin:(id)sender{
    [self openLeftWindow:sender];
}

-(IBAction)openLeftWindow:(id)sender{
    //Code to populate Left Click Window
    [leftWindow makeKeyAndorderFront:nil];
}

-(IBAction)openRightWindow:(id)sender{
    //Code to populate Right Click Window
    [rightWindow makeKeyAndorderFront:nil];
}

在我看来,解决方案可能是 openWin() 函数中的 if 语句来确定单击了哪个按钮(或者是否按住 ctrl)然后运行适当的代码或让菜单知道左键和右键。但是当我试图这样做时,这些都没有奏效。

提前致谢。

【问题讨论】:

  • 我假设 openLeftWindow: 和 openRightWindow: 方法都做同样的事情只是一个错字。否则,这个问题就没用了。
  • 正确,他们做不同的事情。抱歉打错了

标签: cocoa right-click nsstatusitem


【解决方案1】:

如果您对检测到控制单击而不是右键单击感到满意,那么第一个代码块将执行您想要的操作。如果你真的需要右键检测,你将不得不在你的 NSStatusItem 中使用自定义视图而不是图像,并且第二个代码块将起作用。

简单方法:

- (void)openWin:(id)sender {
    NSEvent *event = [NSApp currentEvent];
    if([event modifierFlags] & NSControlKeyMask) {
        [self openRightWindow:nil];
    } else {
        [self openLeftWindow:nil];
    }
}

自定义查看方式:

- (void)awakeFromNib {
    ...
    statusImage = ...
    MyView *view = [MyView new];
    view.image = statusImage;
    [statusItem setView:view];
    [statusItem setToolTip:@"Program Name"];
    view target = self;
    view action = @selector(openLeftWindow:);
    view rightAction = @selector(openRightWindow:);
    [view release];
    //[statusImage release]; //If you are not using it anymore, you should release it.
}

MyView.h

#import <Cocoa/Cocoa.h>
@interface MyView : NSControl {
    NSImage *image;
    id target;
    SEL action, rightAction;
}
@property (retain) NSImage *image;
@property (assign) id target;
@property (assign) SEL action, rightAction;
@end

MyView.m

#import "MyView.h"
@implementation MyView
@synthesize image, target, action, rightAction;
- (void)mouseUp:(NSEvent *)event {
    if([event modifierFlags] & NSControlKeyMask) {
        [NSApp sendAction:self.rightAction to:self.target from:self];
    } else {
        [NSApp sendAction:self.action to:self.target from:self];
    }
}
- (void)rightMouseUp:(NSEvent *)event {
    [NSApp sendAction:self.rightAction to:self.target from:self];
}
- (void)dealloc {
    self.image = nil;
    [super dealloc];
}
- (void)drawRect:(NSRect)rect {
    [self.image drawInRect:self.bounds fromRect:NSZeroRect operation:NSCompositeSourceOver fraction:1];
}
@end

【讨论】:

  • 第二个解决方案正是我想要的。但是图标没有出现在状态栏中。我可以单击(左、右和 ctrl)图标应该在的位置,效果很好,但图标本身不见了。
  • 对不起,我忘了把drawRect:方法放进去。我会把它添加到我的帖子中。
  • 手动设置图标大小后,效果很好!谢谢!
  • 嗯...现在是小问题。它打开的窗口包含运行外部程序和网站的链接和命令。当我点击这些链接和按钮时,图标会消失,即使我点击图标所属的区域,它仍然会运行。几乎就像以前的问题一样,但现在图像最初就在那里,但当我使用打开外部内容的链接/按钮时不会持续存在。
  • @Atheist 假设你使用的是视图方式,你可以尝试在你的视图中使用menuForEvent: 方法来返回一个菜单,但我不知道它在一个状态下是否能正常工作物品。如果没有,则需要使用rightMouseUp: 方法并调用popUpContextMenu:withEvent:forView: 手动显示菜单。
【解决方案2】:

我会创建一个视图并使用状态项方法。

-setView:

然后在子类视图中,您可以使用以下方法检测 ctrl+LMB

- (void)mouseDown:(NSEvent *)theEvent
{
    [super mouseDown:theEvent];

    //Respond to the mouse click
    if ([theEvent modifierFlags] & NSCommandKeyMask) //Command + LMB
    {       
      //Do something
    }
}

我想你可以弄清楚其余的。

【讨论】:

    【解决方案3】:

    更简化的响应(注意,仅适用于 control + click)

    属性:

    @property (strong, nonatomic) NSStatusItem *statusItem;
    @property (weak) IBOutlet NSMenu *statusMenu;
    

    在您的应用程序中加载:

    [self.statusItem setAction:@selector(itemClicked:)];
    

    点击功能:

    - (void)itemClicked:(id)sender
    {
        NSEvent *event = [NSApp currentEvent];
    
        if([event modifierFlags] & NSControlKeyMask) {
            NSLog(@"Right Click Pressed");
            [self.statusItem popUpStatusItemMenu:self.statusMenu];
    
        } else {
            // Do Nothing
            NSLog(@"Left Click Pressed");
        }
    }
    

    【讨论】:

      猜你喜欢
      • 2011-01-11
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2011-01-29
      相关资源
      最近更新 更多