Обработка сообщения какао setAction в Objective-C ++ - PullRequest
2 голосов
/ 21 января 2012

Как вы обрабатываете сообщение setAction в Objective-C ++? ( Не объективно-C. )

Например, предположим, что у меня есть:

my_class.mm

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

Приложение: я программирую на Qt (C ++) и мне нужна оболочка для некоторых виджетов Какао, которые я хочу использовать напрямую. Я наследую от QMacCocoaViewContainer, но не могу понять, как обрабатывать "щелчки" NSSegmentedControl, который я упаковываю. В конце концов это выдаст стандартный сигнал Qt.

Ответы [ 3 ]

4 голосов
/ 21 января 2012

action - это просто селектор - он используется в паре с target. поэтому напишите метод objc для target + action, который вызывает или делает то, что вам действительно нужно. actions 'аргументы - отправитель, но вы можете пропустить это, если вам это не нужно. отправитель будет тем, кто отправляет сообщение (например, элемент управления). в ObjC ++ она ничем не отличается - это должно быть заключено в метод objc, потому что целью должен быть объект objc.

так бы это выглядело так:

obj.action = @selector(pressDoStuff:);

и метод:

- (void)pressDoStuff:(id)sender
1 голос
/ 25 января 2012

@ У Джастина правильный ответ; Я приму это, но также включу окончательное решение на случай, если оно поможет другим. Трюк в том, что вам нужен прокси-класс, как заметил @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 голосов
/ 07 июля 2013

Я слежу за ответом Дэйва Мейтера (это было очень полезно!).

У меня были проблемы с установкой цели C ++ (изнутри класса target-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 ++.

Внутри прокси-класса вам необходимо использовать метод pointerValue NSValue, а затем привести обратно к классу C ++, чтобы отправить ему сообщение.

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

Меня впервые предупредили об уловке "valueWithPointer" в этом посте .

...