Иногда бывают случаи, когда необходимо добавить в программу платформо-зависимый код, и, если в Linux и Windows все стандартные заголовки являются C/C++ заголовками, то в среде MacOSX это Objective-C заголовки, и если их просто подключить в проект, вы получите тысячи и тысячи ошибок сборки, поэтому для MacOSX необходима возможность писать часть кода на Objective-C, и такая возможность есть.
Разбирать будем на примере перехвата глобального сочетания горячих клавиш с помощью платформозависимого метода
bool QApplication::macEventFilter(EventHandlerCallRef caller, EventRef event).
Если переопределить этот виртуальный метод, вы будете получать вообще все event'ы от опереционной системы в него, соответственно нам необходимо отфильтровать то, что нас интересует и отдать управление дальше в ином случае, чтобы проигнорировать событие данный метод просто должен вернуть false. Но для того, чтобы проверить событие event, нам необходимо сконвертировать его в NSEvent * - класс из MacOSX API.
Итак, первое что нужно сделать, это объявить в каком-нибудь заголовочном файле функцию нашего обработчика (скорее всего это будет заголовок вашего класса наследника от QApplication):
#ifdef Q_WS_MAC bool eventHandler(EventRef e); #endifДалее мы создаем файл с телом этой функции и расширением .mm, назовем его mac_helper.mm:
#include <QtDebug> #ifdef QT_MAC_USE_COCOA #import <Cocoa/Cocoa.h> bool eventHandler(EventRef e) { NSEvent *event = reinterpret_cast<NSEvent *>(e); Q_ASSERT(event); if ([event type] == NSKeyDown) { if ([event modifierFlags] & NSShiftKeyMask) { if ([event keyCode] == 0x44) { qDebug() << "Hello key event!"; return true; } } } return false; } #endifВ этом файле мы видим тело нашей функции написанное уже на Objective-C, хотя, как вы можете заметить, мы смело используем обычный qDebug(), и это будет работать.
Осталось только вызвать наш обработчик из QApplication:
#ifdef Q_WS_MAC bool RMS_Keyboards_Application::macEventFilter(EventHandlerCallRef, EventRef e) { return eventHandler(e); } #endifИ не забыть добавить .mm файл в проект, это делается таким образом:
mac {
OBJECTIVE_SOURCES += mac_helper.mm
}
Кстати, для заголовков на Objective-C тоже есть директива, она, как не трудно догадаться называется: OBJECTIVE_HEADERS.На этом все.
День добрый и с Новым Годом!
ReplyDeleteУ меня так и не получилось подружить Qt с objective-C... :(
>#ifdef QT_MAC_USE_COCOA
- данный флаг у меня выключен, включить надобно где-то в настройках проекта? Где именно? Или пересобрать Qt (какие флаги надо будет установить при сборке)?
>#import
- сорри, не нашёл данной библиотечки на своём маке... Не подскажете, где её искать? Или это связано с ответом на вопрос выше?
Буду премного благодарен за Ваши ответы или разъяснения