将C函数设置为NSButton的选择器不会产生任何结果

时间:2014-12-25 01:57:07

标签: objective-c cocoa nsbutton target-action

我有一个创建按钮实例的函数,我希望回调转到一个单独的函数。这不起作用(没有错误或任何事情,当我点击按钮时没有任何反应)。我需要它是一个C函数,因为我正在使用Golang(使用cgo)。

void Start(void){
    ...
    NSRect buttonFrame = NSMakeRect(59, 33, 82, 32);
    NSButton *button = [[NSButton alloc] initWithFrame:buttonFrame];
    [button setAction:@selector(ButtonClick:)];
    ...
}
void ButtonClick(void){
    NSLog(@"Button clicked!");
}

2 个答案:

答案 0 :(得分:3)

您不能将C函数用作NSButton的操作。该按钮需要target which is an object and the selector for a method on that target。如果没有目标,则您的窗口responder chain中仍有一个对象会响应选择器。

您必须创建一个对象(不必是一个实例;如果您愿意,可以使用类对象)以使按钮运行。该方法还需要有一个特定的签名:它必须带一个参数,当它被调用时,它将成为按钮。

如果你必须使用你已经编写的功能,你必须编写一个ObjC类,通过action方法调用它:

#import <Cocoa/Cocoa.h>

@interface ButtonPasser : NSObject

+ (IBAction)buttonPassthrough:(id)sender;

@end

@implementation ButtonPasser

+ (IBAction)buttonPassthrough:(id)sender
{
    buttonClick();
}

@end

void start(void){
    ...
    NSRect buttonFrame = NSMakeRect(59, 33, 82, 32);
    NSButton *button = [[NSButton alloc] initWithFrame:buttonFrame];
    [button setTarget:[ButtonPasser class]];
    [button setAction:@selector(buttonPassthrough:)];
    ...
}

这使用了类对象和类方法,因为我不确定在创建实例后你会对它做什么。但是,使用实例会更常见。

答案 1 :(得分:1)

您的问题是您的Start或ButtonClick方法(应该是start和buttonClick)都不是实例方法。它们都必须绑定到一个对象,以便将buttonClick设置为一个动作。

一旦这些都是实例方法,您应该能够在setAction调用之上添加[button setTarget:self];

如果您无法启动实例方法,则应在调用之间添加其他方法。