Благодаря тому, что Qt это обычный С++ и собирается он обычным GCC (любым компилятором на ваш вкус) мы, при небольшой сноровке и соблюдении нехитрых правил, можем использовать любой платформозависимый код на Objective-C и любые платформозависимые фреймворки. А значит можем сделать качественное приложение для MacOS X, интегрированное в систему по всем правилам приличия.
Правило первое. Весь Objective-C код должен быть в m (Objective-C) и mm (Objective-C++) файлах. GCC распознает язык содержимого именно по расширению файла, если ему встретится код на Objective-C в любом другом файле, то выдаст несколько тысяч ошибок. Не смертельно, но больно долго ждать, если пользуетесь QtCreator. Никакого Objective-C кода в заголовочных файлах!
Правило два. Следует из первого правила. Для удобства, всю работу с Objective-C сущностями надо заворачивать в С++ классы. Тогда проблем с заголовками не будет.
Правило три. Заворачивайте все включения платформозависимого кода в
#ifdef Q_WS_MAC #endif
. Поможет сэкономить кучу времени потом.Правило четыре. Не забываем подключать нужные фреймворки в pro-файле.
LIBS += -framework Cocoa -framework Carbon
Правило пять. Если вы используете Cocoa, то для нормальной работы должны создать объект типа NSAutoreleasePool, который будет вести учет всех autorelease объектов. В справке Qt об этом написано. Зато не написано что пул должен существовать на протяжении всего времени использования объектов Cocoa. Пример из справки игнорирует это правило и использует пул лишь в конструкторе объектов, в результате чего гарантированы утечки памяти и куча эксепшенов в фоне. Для решения этой проблемы можно использовать наследника QApplication, который будет создавать пул в конструкторе и уничтожать в деструкторе.
qtcocoaapplication.h
#ifndef COCOAAPPLICATION_H
#define COCOAAPPLICATION_H
#import <QtCore>
#import <QtGui>
class QCocoaApplication : public QApplication
{
Q_OBJECT
public:
QCocoaApplication(int &argc, char **argv);
~QCocoaApplication();
};
#endif // COCOAAPPLICATION_H
qtcocoaapplication.mm
#import "qtcocoaapplication.h"
#import <QtCore>
#import <QtGui>
#import <Cocoa/Cocoa.h>
// just for safe
static QMutex mutex;
static int usedPool = 0;
static NSAutoreleasePool * pool = 0;
QCocoaApplication::QCocoaApplication(int &argc, char **argv) : QApplication(argc, argv)
{
mutex.lock();
if (!usedPool) pool = [[NSAutoreleasePool alloc] init];
usedPool++;
mutex.unlock();
};
QCocoaApplication::~QCocoaApplication()
{
mutex.lock();
--usedPool;
if (!usedPool) [pool release];
mutex.unlock();
};
а main.cpp сделать по такому шаблону
#include <QtGui/QApplication>
#ifdef Q_WS_MAC
#include "QtCocoa/qtcocoaapplication.h"
#include "macmainwindow.h"
int main(int argc, char **argv)
{
QCocoaApplication app(argc, argv);
// optional
//app.setQuitOnLastWindowClosed(false);
MacMainWindow mainWindow;
mainWindow.show();
return app.exec();
}
#else
int main(int argc, char **argv)
{
QApplication app(argc, argv);
QLabel label;
label.resize(300, 200);
label.setText(" This application is platform-specific and requires Mac OS X.");
label.show();
return app.exec();
}
#endif
Добавляем в главных окнах
setUnifiedTitleAndToolBarOnMac(true)
по-вкусу и пользуемся новыми возможностями.
Комментариев нет:
Отправить комментарий