在NSButton上悬停事件以显示图像

时间:2022-03-05 09:01:05

So I am trying to make an application that has a button (doesn't have to be a button) that when you hover over it a pop-up window appears. I have been able to print a message to the log when i hover over the button, but I can't figure out how to set the Hidden property of the image to NO. I tried giving the NSButtonCell (the class that receives the hover event) a delegate, but calling

因此,我试图创建一个具有按钮(不必是按钮)的应用程序,当您将鼠标悬停在按钮上时会出现一个弹出窗口。当我将鼠标悬停在按钮上时,我能够将消息打印到日志中,但我无法弄清楚如何将图像的隐藏属性设置为NO。我尝试给NSButtonCell(接收悬停事件的类)一个委托,但是调用

[myButtonCell setDelegate:delegateObject]

Doesn't give the object a delegate. If I could find a way for the buttonCell and image to communicate (they are both in the same xib) or get the buttonCell to call a function in one of the classes which has it as an instance it would be an easy task to figure out the rest.

不给对象一个委托。如果我能找到一种方法让buttonCell和图像进行通信(它们都在同一个xib中)或者让buttonCell调用其中一个类中的一个函数作为一个实例,那么找出它将是一件容易的事。其余的部分。

My explanation is a bit diffuse so I will try to explain better: I have a window object, with a view object, which has a subclass of a NSButtonCell object (IBOutlet). In the subclass of the NSButtonCell (lets call it MyButtonCell) I have a method that when call needs to inform the view, or the window, that the method has been called.

我的解释有点弥漫,所以我将尝试更好地解释:我有一个带有视图对象的窗口对象,它有一个NSButtonCell对象的子类(IBOutlet)。在NSButtonCell的子类中(我们称之为MyButtonCell)我有一个方法,当调用需要通知视图或窗口时,方法已被调用。

I feel like I have looked everywhere, but can't find the solution. I thought I would make it with a delegate, but I can't set a delegate for the buttonCell so I am stuck…

我觉得我到处都是,但找不到解决方案。我以为我会用委托制作它,但是我不能为buttonCell设置委托,所以我被卡住了......

Edit:

编辑:

Here is the code for the NSButtonCell and the Delegate: The delegate:

以下是NSButtonCell和Delegate的代码:委托:

@interface MyView : NSView <MyButtonCellDelegate>
    {

    }
@property (assign) IBOutlet MyButtonCell *buttonCell1;
    - (void)toggleField:(int)fieldID;
@end

@implementation MyView

- (void)toggleField:(int)fieldID
{
    if (fieldID == 1) {
        [self.field1 setHidden:!buttonCell1.active];
    }
    NSLog(@"toggling");
}
@end

MyButtonCell:

MyButtonCell:

@protocol MyButtonCellDelegate

- (void)toggleField:(int)fieldID;

@end

@interface MyButtonCell : NSButtonCell
{
    id <MyButtonCellDelegate> delegate;
}

@property BOOL active; //Used to lett the view know wether the mouse hovers over it
@property (nonatomic, assign) id  <DuErButtonCellDelegate> delegate;

-(void)_updateMouseTracking; //mouse tracking function, if you know a better way to do it that would be lovely

@end

@implementation MyButtonCell

@synthesize delegate;
@synthesize active;

- (void)mouseEntered:(NSEvent *)event
{
    active = YES;
    [[self delegate] toggleField:1];
    NSLog(@"entered");
}

- (void)mouseExited:(NSEvent *)event
{
    active = NO;
    [[self delegate] toggleField:1];
}

- (void)_updateMouseTracking {
    [super _updateMouseTracking];
    if ([self controlView] != nil && [[self controlView] respondsToSelector:@selector(_setMouseTrackingForCell:)]) {
        [[self controlView] performSelector:@selector(_setMouseTrackingForCell:) withObject:self];
    }


}

@end

Hope this is clear enough

希望这很清楚

1 个解决方案

#1


1  

I am not sure what you are really looking for, but if I understand what you are asking here:

我不确定你在寻找什么,但如果我明白你在这里问的是什么:

I have a window object, with a view object, which has a subclass of a NSButtonCell object (IBOutlet). In the subclass of the NSButtonCell (lets call it MyButtonCell) I have a method that when call needs to inform the view, or the window, that the method has been called.

我有一个带有视图对象的窗口对象,它有一个NSButtonCell对象的子类(IBOutlet)。在NSButtonCell的子类中(我们称之为MyButtonCell)我有一个方法,当调用需要通知视图或窗口时,方法已被调用。

correctly, one possibility is for your NSButtonCell to post a NSNotification to the default notification center and have your view or window or whoever needs to know be an observer for that notification. You are free to define your own custom notifications.

正确地说,一种可能性是NSButtonCell将NSNotification发布到默认通知中心,并让您的视图或窗口或任何需要知道的人成为该通知的观察者。您可以*定义自己的自定义通知。

Another possibility would be for your subclass of NSButtonCell to use:

另一种可能性是NSButtonCell的子类使用:

- (void)performSelectorOnMainThread:(SEL)aSelector withObject:(id)arg waitUntilDone:(BOOL)wait

and from your NSCell method that, when invoked, needs to inform it's view or window, can do:

并且从你的NSCell方法中,当被调用时,需要通知它的视图或窗口,可以这样做:

[[self controlView] performSelectorOnMainThread:@selector( viewMethodToInvoke: ) withObject:anObject waitUntilDone:YES]

or

要么

[[[self controlView] window] performSelectorOnMainThread:@selector( windowMethodToInvoke: ) withObject:anObject waitUntilDone:YES]

A third possibility is to do as you suggest and provide your NSButtonCell with an object that it can send a message to directly, but this is just the same thing as using performSelectorOnMainThread on the controlView or the controlView's window, but more work.

第三种可能性是按照你的建议做,并为你的NSButtonCell提供一个可以直接发送消息的对象,但这与在controlView或controlView的窗口上使用performSelectorOnMainThread是一回事,但更多的工作。

As for your mouse tracking code, I assume that you are using a NSTrackingArea. You can find documentation on them here: Using Tracking-Area Objects

至于你的鼠标跟踪代码,我假设你使用的是NSTrackingArea。您可以在此处找到有关它们的文档:使用跟踪区域对象

#1


1  

I am not sure what you are really looking for, but if I understand what you are asking here:

我不确定你在寻找什么,但如果我明白你在这里问的是什么:

I have a window object, with a view object, which has a subclass of a NSButtonCell object (IBOutlet). In the subclass of the NSButtonCell (lets call it MyButtonCell) I have a method that when call needs to inform the view, or the window, that the method has been called.

我有一个带有视图对象的窗口对象,它有一个NSButtonCell对象的子类(IBOutlet)。在NSButtonCell的子类中(我们称之为MyButtonCell)我有一个方法,当调用需要通知视图或窗口时,方法已被调用。

correctly, one possibility is for your NSButtonCell to post a NSNotification to the default notification center and have your view or window or whoever needs to know be an observer for that notification. You are free to define your own custom notifications.

正确地说,一种可能性是NSButtonCell将NSNotification发布到默认通知中心,并让您的视图或窗口或任何需要知道的人成为该通知的观察者。您可以*定义自己的自定义通知。

Another possibility would be for your subclass of NSButtonCell to use:

另一种可能性是NSButtonCell的子类使用:

- (void)performSelectorOnMainThread:(SEL)aSelector withObject:(id)arg waitUntilDone:(BOOL)wait

and from your NSCell method that, when invoked, needs to inform it's view or window, can do:

并且从你的NSCell方法中,当被调用时,需要通知它的视图或窗口,可以这样做:

[[self controlView] performSelectorOnMainThread:@selector( viewMethodToInvoke: ) withObject:anObject waitUntilDone:YES]

or

要么

[[[self controlView] window] performSelectorOnMainThread:@selector( windowMethodToInvoke: ) withObject:anObject waitUntilDone:YES]

A third possibility is to do as you suggest and provide your NSButtonCell with an object that it can send a message to directly, but this is just the same thing as using performSelectorOnMainThread on the controlView or the controlView's window, but more work.

第三种可能性是按照你的建议做,并为你的NSButtonCell提供一个可以直接发送消息的对象,但这与在controlView或controlView的窗口上使用performSelectorOnMainThread是一回事,但更多的工作。

As for your mouse tracking code, I assume that you are using a NSTrackingArea. You can find documentation on them here: Using Tracking-Area Objects

至于你的鼠标跟踪代码,我假设你使用的是NSTrackingArea。您可以在此处找到有关它们的文档:使用跟踪区域对象