2012-01-20 24 views
2

如何处理Objective-C++中的setAction消息? (不客观-C在Objective-C++中处理Cocoa setAction消息

例如,假设我有:

my_class.mm

NSSegmentedControl *segmented = [[NSSegmentedControl alloc] init]; 
[segmented setSegmentCount:5]; 
// etc. 
[segmented setAction:???]; 

应用:我在Qt的(C++)编程和需要的包装围绕我想直接使用的一些Cocoa小部件。我从QMacCocoaViewContainer继承,但无法弄清楚如何处理我打包的NSSegmentedControl的“点击”。最终这会发出一个标准的Qt信号。

回答

4

action只是一个选择器 - 它与target一起使用。所以写一个objc方法来调用目标+动作,或者做你真正想要的东西。 actions'参数是发送者,但如果你不需要它,你可以忽略它。发送者将是发送消息的任何东西(例如控件)。它在ObjC++中没有什么不同 - 它必须包装在objc方法中,因为目标必须是objc对象。

所以它看起来像这样:

obj.action = @selector(pressDoStuff:); 

和方法是:

- (void)pressDoStuff:(id)sender 
+2

@Justin说什么。我最终编写了许多具有调用C++方法的Objective C方法的小代理Objective C类。 – smparkes

+0

这是给我“预期的非限定id之前” - “令牌”编译错误。 –

+0

@Dave我发布的代码没有任何问题。你把它放在正确的地方吗?并且您的源代码是作为ObjC或ObjC++编译的? – justin

1

@Justin有正确的答案;我会接受它,但也包括最终的解决方案,以帮助其他人。诀窍是你需要一个代理类,正如@smparkes指出的那样。

忽略了简洁的.h文件:

mac_control.mm

MacControl::MacControl(QWidget *parent) : QMacCocoaViewContainer(NULL, parent) { 
    NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init]; 

    NSSegmentedControl *segmented = [[NSSegmentedControl alloc] init]; 
    // Set up NSSegmentedControl... 

    // The proxy class marshalls between Objective-C and C++. 
    proxy_ = [[MacControlProxy alloc] init]; 
    [proxy_ setTarget:this]; 
    [segmented setTarget:proxy_]; 
    [segmented setAction:@selector(handleToggle:)]; 

    setCocoaView(segmented); 
    [segmented release]; 

    [pool release]; 
} 

MacControl::~MacControl() { 
    delete proxy_; 
} 

void MacControl::TriggerAction(int index) { 
    // Trigger the action in Qt/C++. 
} 

mac_control_proxy.mm

@implementation MacControlProxy 

- (id)init { 
    [super init]; 
    target_ = NULL; 
    return self; 
} 

-(void) handleToggle: (id)sender { 
    if (target_) { 
    target_->TriggerAction([sender selectedSegment]); 
    } 
} 

-(void) setTarget: (MacToolbarButtonControlImpl*)target { 
    target_ = target; 
} 

@end 
0

我戴夫狄考文的回答跟进(这是超级有用!)。

我在设置C++目标(来自Objective-C++类)并且使用[NSValue valueWithPointer:theTargetCxxClass]将目标传递给Proxy.mm类时遇到了问题。

所以,我的Objective-C++类的内部,而不是这样做:

[proxy_ setTarget:this]; 

我这样做:

[proxy_ setTarget:[NSValue valueWithPointer:this]]; 

[proxy_ setTarget:[NSValue valueWithPointer:ptrToMyCxxObject]]; 

而且这样做整肃关于将C++类(不扩展类型“id”)传递给Objective-C++代理类的错误。

在代理类的内部,您需要使用NSValue的pointerValue方法,然后将其转换回C++类以向其发送消息。

-(void) myButtonAction: (id)sender { 
    ((MyCxxClass*)[target pointerValue])->someMethodInMyCxxClass(); 
} 

我第一次被警告到this post中的“valueWithPointer”技巧。