C++ 在Objective-C+中处理操作消息+;

C++ 在Objective-C+中处理操作消息+;,c++,cocoa,qt,objective-c++,C++,Cocoa,Qt,Objective C++,如何处理Objective-C++中的setAction消息?(不客观——C) 例如,假设我有: 我的班级。mm NSSegmentedControl *segmented = [[NSSegmentedControl alloc] init]; [segmented setSegmentCount:5]; // etc. [segmented setAction:???]; MacControl::MacControl(QWidget *parent) : QMacCocoaViewCont

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

例如,假设我有:

我的班级。mm

NSSegmentedControl *segmented = [[NSSegmentedControl alloc] init];
[segmented setSegmentCount:5];
// etc.
[segmented setAction:???];
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++.
}
@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

应用:我正在用Qt(C++)编程,需要一个包装器来包装一些我想直接使用的Cocoa小部件。我继承了
qmacocaoviewcontainer
,但不知道如何处理我正在包装的
NSSegmentedControl的“点击”。最终,这将发出一个标准的Qt信号。

操作
只是一个选择器-它与
目标
一起使用。因此,为target+操作编写一个objc方法,该方法通过调用或执行您真正想要的操作
actions
'参数是发送方,但如果不需要,可以忽略它。发送者将是发送消息的任何人(例如控件)。在ObjC++中没有什么不同-这必须包装在ObjC方法中,因为目标必须是ObjC对象

所以看起来是这样的:

obj.action = @selector(pressDoStuff:);
方法是:

- (void)pressDoStuff:(id)sender
@贾斯汀有正确的答案;我会接受它,但也包括最终的解决方案,以防它对其他人有帮助。技巧是您需要一个代理类,正如@smparkes所指出的

为简洁起见,忽略
.h
文件:

mac_control.mm

NSSegmentedControl *segmented = [[NSSegmentedControl alloc] init];
[segmented setSegmentCount:5];
// etc.
[segmented setAction:???];
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++.
}
@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
mac\u control\u proxy.mm

NSSegmentedControl *segmented = [[NSSegmentedControl alloc] init];
[segmented setSegmentCount:5];
// etc.
[segmented setAction:???];
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++.
}
@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

我正在跟进Dave Mateer的答案(这非常有帮助!)

<>我有问题设置C++目标(从ObjuleC++类中),并使用[NSvaleValueWuffoCyth:THECTARGCXXClass ]将目标传递给PROXY.MM类。

因此,在我的Objective-C++类中,而不是这样做:

[proxy_ setTarget:this];
我这样做:

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

这样做,消除了将C++类(不扩展类型“ID”)传递给ObjtoVC++代理类的错误。

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

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

我第一次被提醒注意“valueWithPointer”的把戏。

What@Justin说的。最后,我编写了许多代理代理类C类,这些类都有C++调用的方法,这是给我“预期的不合格ID”-“令牌”编译错误。@戴夫,我发布的代码没有错。你放对地方了吗?您的源代码编译为ObjC还是ObjC++?