Qt für macOS – Spezifische Probleme
Auf dieser Seite werden die wichtigsten Aspekte der macOS-Unterstützung in Qt beschrieben. macOS-Fachbegriffe und spezifische Vorgehensweisen finden Sie unter https://developer.apple.com/.
Aqua
Der Aqua-Stil ist ein wesentlicher Bestandteil der macOS-Plattform. Wie bei Cocoa stellt Qt Widgets bereit, die den in den macOS Human Interface Guidelines beschriebenen Widgets entsprechen. Beachten Sie, dass die Qt-Widgets zwar intern AppKit für das Look-and-Feel nutzen, jedoch nicht jedes einzelne Qt-Widget als verpacktes natives Steuerelement darstellen.
Die Seite „Qt Widget Gallery“ enthält Beispielbilder von Anwendungen, die das Design der macOS-Plattform verwenden.
Qt-Attribute für macOS
Im Folgenden sind einige nützliche Attribute aufgeführt, mit denen sich Anwendungen unter macOS anpassen lassen:
- Qt::AA_PluginApplication
- Qt::AA_DontUseNativeMenuBar
- Qt::AA_MacDontSwapCtrlAndMeta
- Qt::WA_MacOpaqueSizeGrip
- Qt::WA_MacShowFocusRect
- Qt::WA_MacNormalSize
- Qt::WA_MacSmallSize
- Qt::WA_MacMiniSize
- Qt::WA_MacAlwaysShowToolWindow
- Qt::Sheet
- Qt::Drawer
- Qt::MacWindowToolBarButtonHint,
- QMainWindow::unifiedTitleAndToolBarOnMac
macOS verwendet stets einen Doppelpuffer für den Bildschirm, daher hat das Attribut „ Qt::WA_PaintOnScreen “ keine Wirkung. Außerdem ist es nicht möglich, außerhalb eines Paint-Ereignisses zu zeichnen, sodass auch „Qt::WA_PaintOutsidePaintEvent“ keine Wirkung hat.
Rechtsklicks
Die Klasse ` QContextMenuEvent ` bietet Unterstützung für Rechtsklicks in macOS-Anwendungen. Dies wird einem Kontextmenü-Ereignis zugeordnet, beispielsweise einem Menü, das eine Popup-Auswahl anzeigt. Dies ist die häufigste Verwendung von Rechtsklicks und entspricht einem Control-Klick bei der Unterstützung von Ein-Tasten-Mäusen unter macOS.
Internationalisierung
Anwendungen unter macOS geben ihre unterstützten Sprachen als Teil der „ Info.plist “ der Anwendung an. Das System gleicht dann die von der Anwendung unterstützten Sprachen mit den Spracheinstellungen des Benutzers ab, um die Locale zu bestimmen, in der die Anwendung gestartet wird. Dies bestimmt wiederum die Reihenfolge der Sprachen, die über ` QLocale::uiLanguages()` widergespiegelt wird, sowie die Art und Weise, wie System-Frameworks wie AppKit ihre lokalisierten Ressourcen – beispielsweise Menütitel und Zeichenfolgen – abrufen.
Da Qt-Anwendungen standardmäßig nicht übersetzt sind, wird in der standardmäßig generierten Datei „ Info.plist “ für Projekte vom Typ „ CMake “ und „ qmake “ CFBundleAllowMixedLocalizations auf „ YES “ gesetzt, damit System-Frameworks die Lokalisierung auswählen können, die den Spracheinstellungen des Benutzers am besten entspricht – selbst wenn diese Lokalisierung für die Anwendung selbst nicht verfügbar ist. Sobald Sie Ihrer Anwendung über ` qt_add_translations` Übersetzungen hinzufügen, wird der CFBundleAllowMixedLocalizations Schlüssel automatisch entfernt und durch CFBundleLocalizationsersetzt, der alle von Ihnen unterstützten Sprachen auflistet. Für „ qmake “ muss dieser Vorgang manuell durchgeführt werden.
Menüleiste
Qt erkennt Menüleisten und wandelt sie in native Mac-Menüleisten um. Die Integration in bestehende Qt-Anwendungen erfolgt normalerweise automatisch. Wenn Sie jedoch spezielle Anforderungen haben, wählt die Qt-Implementierung derzeit eine Menüleiste aus, indem sie beim aktiven Fenster beginnt (zum Beispiel QGuiApplication::focusWindow()) und die folgenden Prüfungen durchführt:
- Wenn das Fenster über ein ` QMenuBar` verfügt, wird dieses verwendet.
- Ist das Fenster modal, wird dessen Menüleiste verwendet. Ist keine Menüleiste angegeben, wird eine Standard-Menüleiste verwendet (wie unten beschrieben).
- Wenn das Fenster kein übergeordnetes Fenster hat, wird die Standard-Menüleiste verwendet (wie unten beschrieben).
Diese Prüfungen werden entlang der gesamten Kette der übergeordneten Fenster durchgeführt, bis eine der oben genannten Regeln erfüllt ist. Wenn alle anderen Möglichkeiten scheitern, wird eine Standardmenüleiste erstellt. Die Standardmenüleiste in Qt ist eine leere Menüleiste. Sie können jedoch eine andere Standardmenüleiste erstellen, indem Sie eine übergeordnete Fensterkomponente ( QMenuBar) ohne übergeordnetes Fenster anlegen. Die zuerst erstellte wird als Standardmenüleiste festgelegt und immer dann verwendet, wenn eine Standardmenüleiste benötigt wird.
Die Verwendung nativer Menüleisten bringt gewisse Einschränkungen für Qt-Klassen mit sich. Weitere Informationen finden Sie im folgenden Abschnitt mit der Liste der Einschränkungen.
Qt bietet Unterstützung für die globale Menüleiste mit ` QMenuBar`. macOS-Benutzer erwarten eine Menüleiste am oberen Bildschirmrand, und Qt berücksichtigt dies.
Darüber hinaus erwarten Benutzer, dass bestimmte Konventionen eingehalten werden, beispielsweise sollte das Anwendungsmenü die Einträge „Über“, „Einstellungen“, „Beenden“ usw. enthalten. Qt berücksichtigt diese Konventionen, bietet jedoch keine Möglichkeit zur direkten Interaktion mit dem Anwendungsmenü.
Jedes „ QAction “ verfügt über die Eigenschaft „ menuRole “, die die spezielle Anordnung der Anwendungsmenüelemente steuert; standardmäßig ist der „ menuRole “ jedoch auf „ TextHeuristicRole “ gesetzt, was bedeutet, dass die Menüelemente anhand ihrer „ text “ automatisch erkannt werden.
Andere Standardmenüelemente wie „Ausschneiden“, „Kopieren“, „Einfügen“ und „Alles auswählen“ sind sowohl in Ihrer Anwendung als auch in einigen nativen Dialogen wie „ QFileDialog “ verfügbar. Es ist wichtig, dass Sie diese Menüelemente mit den Standard-Tastenkombinationen erstellen, damit die entsprechenden Bearbeitungsfunktionen in den Dialogen aktiviert werden. Derzeit gibt es keine „ MenuRole “-Bezeichner für diese Funktionen, sie werden jedoch genau wie die Menüpunkte der Anwendung automatisch erkannt, wenn die „ QAction “ den Standardwert „ TextHeuristicRole “ aufweist.
Sondertasten
Um das erwartete Verhalten für Qt-Anwendungen unter macOS zu gewährleisten, entsprechen die Enum-Werte „ Qt::Key_Meta “, „ Qt::MetaModifier “ und „ Qt::META “ den Control-Tasten auf der Standard-Apple-Tastatur, während die Enum-Werte „ Qt::Key_Control “, „ Qt::ControlModifier “ und „ Qt::CTRL “ den Command-Tasten entsprechen.
Dock
Eine Interaktion mit dem Dock ist möglich. Das Symbol kann durch den Aufruf von ` QWindow::setIcon()` aus dem Hauptfenster Ihrer Anwendung festgelegt werden. Der Aufruf von `setIcon()` kann so oft wie nötig erfolgen, sodass das Symbol leicht aktualisiert werden kann.
Barrierefreiheit
Viele Benutzer interagieren mit macOS mithilfe von Hilfsgeräten. Mit Qt soll dies in Ihrer Anwendung automatisch erfolgen, damit sie den auf der jeweiligen Plattform geltenden Konventionen entspricht. Qt nutzt das Barrierefreiheits-Framework von Apple, um Benutzern mit Behinderungen den Zugriff zu ermöglichen.
Bibliotheks- und Bereitstellungsunterstützung
Qt bietet Unterstützung für macOS-Strukturen wie Frameworks und Bundles. Es ist wichtig, diese Strukturen zu kennen, da sie sich direkt auf die Bereitstellung von Anwendungen auswirken.
Qt stellt mit „macdeployqt“ ein Bereitstellungstool zur Verfügung, das den Bereitstellungsprozess vereinfacht. Der Artikel „Qt für macOS – Bereitstellung“ behandelt den Bereitstellungsprozess ausführlicher.
Qt-Bibliotheken als Frameworks
Standardmäßig wird Qt als eine Reihe von Frameworks kompiliert. Frameworks sind die von macOS bevorzugte Methode zur Verteilung von Bibliotheken. Auf der Website „Framework Programming Guide“ von Apple finden Sie weitaus mehr Informationen zu Frameworks.
Es ist wichtig zu beachten, dass Frameworks immer mit den Release-Versionen der Bibliotheken verknüpft sind. Wenn die Debug-Version eines Qt-Frameworks gewünscht wird, verwenden Sie die Umgebungsvariablen ` DYLD_IMAGE_SUFFIX `, um sicherzustellen, dass die Debug-Version geladen wird:
export DYLD_IMAGE_SUFFIX=_debugAlternativ können Sie Ihre Debug- und Release-Versionen vorübergehend vertauschen. Dies ist in Apples technischem Hinweis „Debugging Magic“ dokumentiert.
Wenn Sie keine Frameworks verwenden möchten, konfigurieren Sie Qt einfach mit ` -no-framework`.
./configure -no-frameworkBundle-basierte Bibliotheken
Wenn Sie dynamische Bibliotheken im macOS-Anwendungsbundle (dem Anwendungsverzeichnis) verwenden möchten, erstellen Sie im Verzeichnis des Anwendungsbundles ein Unterverzeichnis namens „Frameworks“ und legen Sie Ihre dynamischen Bibliotheken dort ab. Die Anwendung findet eine dynamische Bibliothek, wenn diese den Installationsnamen @executable_path/../Frameworks/libname.dylib hat.
Wenn Sie „ qmake “ und Makefiles verwenden, nutzen Sie die Einstellung „ QMAKE_LFLAGS_SONAME “:
QMAKE_LFLAGS_SONAME = -Wl,-install_name,@executable_path/../Frameworks/Alternativ können Sie den Installationsnamen mithilfe des Befehls „ install_name_tool(1) “ über die Befehlszeile ändern.
Die Umgebungsvariable „ DYLD_LIBRARY_PATH “ überschreibt diese Einstellungen sowie alle anderen Standardpfade, wie beispielsweise die Suche nach dynamischen Bibliotheken in /usr/lib und ähnlichen Standardverzeichnissen.
Kombinieren von Bibliotheken
Wenn Sie eine neue dynamische Bibliothek erstellen möchten, die die dynamischen Qt-Bibliotheken kombiniert, müssen Sie das Flag „ ld -r “ setzen. Dadurch werden Relokationsinformationen in der Ausgabedatei gespeichert, sodass diese Datei Gegenstand eines weiteren „ ld “-Laufs sein kann. Dies geschieht durch Setzen des Flags „ -r “ in der Datei „ .pro “ sowie der Einstellungen unter „ LFLAGS “.
Initialisierungsreihenfolge
dyld(1) ruft globale statische Initialisierer in der Reihenfolge auf, in der sie in die Anwendung eingebunden werden. Wenn eine Bibliothek gegen Qt verknüpft ist und auf die globalen Variablen in Qt verweist (über globale Initialisierer in Ihrer eigenen Bibliothek), verknüpfen Sie die Anwendung zunächst gegen Qt, bevor Sie sie gegen die Bibliothek verknüpfen. Andernfalls ist das Ergebnis undefiniert, da die globalen Initialisierer von Qt noch nicht aufgerufen wurden.
Kompilierungsoptionen
Die folgenden Flags sind hilfreich, wenn Sie macOS-spezifischen Code definieren möchten:
Q_OS_DARWINwird definiert, wenn Qt erkennt, dass Sie sich auf einem Darwin-basierten System wie macOS oder iOS befinden.Q_OS_MACOSist definiert, wenn Sie auf einem macOS-System arbeiten.
Hinweis: „ Q_WS_MAC “ ist in Qt 5 und höher nicht mehr definiert.
Wenn Sie Code für bestimmte Versionen von macOS definieren möchten, verwenden Sie die in /usr/include/AvailabilityMacros.h definierten Verfügbarkeitsmakros.
Die Dokumentation zu QSysInfo und QOperatingSystemVersion enthält Informationen zur Versionsprüfung zur Laufzeit.
Zugriff auf die native macOS-API
Zugriff auf den Bundle-Pfad
macOS-Anwendungen sind als Verzeichnis (mit der Endung .app) strukturiert. Dieses Verzeichnis enthält Unterverzeichnisse und Dateien. Es kann sinnvoll sein, Elemente wie Plugins und Online-Dokumentation in diesem Bundle abzulegen. Der folgende Code gibt den Pfad des Anwendungs-Bundles zurück:
#ifdef Q_OS_MAC
QString bundlePath = QString::fromNSString(NSBundle.mainBundle.bundlePath);
qDebug() << "Bundle path =" << bundlePath;
#endifWeitere Informationen zur Verwendung der NSBundle-API finden Sie auf der Entwickler-Website von Apple.
QCoreApplication::applicationDirPathMit () lässt sich der Pfad der Binärdatei innerhalb des Bundles ermitteln.
Verwendung nativer Cocoa-Panels
Der Ereignis-Dispatcher von Qt ist flexibler als der von Cocoa und ermöglicht es dem Benutzer, den Ereignis-Dispatcher (und die Ausführung von „ QEventLoop::exec “) zu steuern, ohne darüber nachdenken zu müssen, ob modale Dialoge auf dem Bildschirm angezeigt werden oder nicht (was einen Unterschied zu Cocoa darstellt). Daher müssen wir in Qt zusätzliche Maßnahmen ergreifen, um dies korrekt zu handhaben, was die Einbindung nativer Panels leider erschwert. Der derzeit beste Weg, dies zu bewerkstelligen, besteht darin, dem unten aufgeführten Muster zu folgen, bei dem wir den Aufruf der Funktion mit nativem Code übermitteln, anstatt sie direkt aufzurufen. So können wir sicher sein, dass Qt alle ausstehenden Rekursionen der Ereignisschleife ordnungsgemäß aktualisiert hat, bevor das native Panel angezeigt wird:
#include <QtGui>
class NativeProxyObject : public QObject
{
Q_OBJECT
public slots:
void execNativeDialogLater()
{
QMetaObject::invokeMethod(this, "execNativeDialogNow", Qt::QueuedConnection);
}
void execNativeDialogNow()
{
NSRunAlertPanel(@"A Native dialog", @"", @"OK", @"", @"");
}
};
#include "main.moc"
int main(int argc, char **argv){
QApplication app(argc, argv);
NativeProxyObject proxy;
QPushButton button("Show native dialog");
QObject::connect(&button, SIGNAL(clicked()), &proxy, SLOT(execNativeDialogLater()));
button.show();
return app.exec();
}Einschränkungen
MySQL und macOS
Es scheint ein Problem zu geben, wenn sowohl -prebind als auch -multi_module definiert sind, wenn statische C-Bibliotheken in dynamische Bibliotheken eingebunden werden. Wenn beim Verknüpfen von Qt XML die folgende Fehlermeldung angezeigt wird:
ld: common symbols not allowed with MH_DYLIB output format with the -multi_module option
/usr/local/mysql/lib/libmysqlclient.a(my_error.o) definition of common _errbuff (size 512)
/usr/bin/libtool: internal link edit command failedVerbinden Sie Qt erneut mit der Option -single_module. Dieses Problem tritt nur auf, wenn der MySQL-Treiber in Qt eingebunden wird. Plugins oder statische Builds sind davon nicht betroffen.
D-Bus und macOS
Das Modul „ QtDBus “ lädt standardmäßig die Bibliothek „libdbus-1“ unter macOS dynamisch. Das bedeutet, dass Anwendungen, die mit dem Modul „ QtDBus “ verknüpft sind, auch auf macOS-Systemen geladen werden, auf denen die Bibliotheken nicht vorhanden sind. Sie können jedoch keine Verbindung zu einem D-Bus-Server herstellen und es gelingt ihnen nicht, einen Server mit dem Befehl „ QDBusServer “ zu öffnen.
Um die D-Bus-Funktionalität nutzen zu können, müssen Sie die Bibliothek „libdbus-1“ installieren, beispielsweise über Homebrew, Fink oder MacPorts. Wenn Sie Ihre Anwendung auf anderen Systemen bereitstellen, sollten Sie diese Bibliotheken möglicherweise in das Bundle Ihrer Anwendung einbinden. Beachten Sie außerdem, dass es unter macOS keinen Systembus gibt und dass der Sitzungsbus erst gestartet wird, nachdem launchd so konfiguriert wurde, dass es diesen verwaltet.
Menüaktionen
- Aktionen in einem „ QMenu “ mit Tastenkombinationen, die aus mehr als einem Tastendruck bestehen (QKeySequence), werden nicht korrekt angezeigt, wenn das „ QMenu “ in eine native Mac-Menüleiste übersetzt wird. Es wird nur die erste Taste angezeigt. Die Tastenkombination wird jedoch weiterhin wie auf allen anderen Plattformen ausgelöst.
- QMenu Objekte, die in der nativen Menüleiste verwendet werden, können Qt-Ereignisse nicht über die normalen Ereignisbehandler verarbeiten. Fügen Sie dem Menü selbst einen Delegaten hinzu, um über diese Änderungen benachrichtigt zu werden. Alternativ können Sie die Signale ` QMenu::aboutToShow()` und ` QMenu::aboutToHide()` verwenden, um die Sichtbarkeit des Menüs zu verfolgen; diese bieten eine Lösung, die auf allen von Qt unterstützten Plattformen funktionieren sollte.
- Standardmäßig erstellt Qt einen nativen Menüpunkt „Beenden“, der auf die Tastenkombination „
CMD+Q“ reagiert. Durch das Erstellen eines „ QAction “ für die Rolle „ QAction::QuitRole “ wird dieser Menüpunkt ersetzt. Daher sollte die Ersatzaktion entweder mit dem Slot „ QCoreApplication::quit “ oder mit einem benutzerdefinierten Slot verbunden werden, der die Anwendung beendet.
Native Widgets
Qt unterstützt „Sheets“, die durch das Fenster-Flag „ Qt::Sheet “ dargestellt werden.
Wenn von einer nativen macOS-Anwendung die Rede ist, bedeutet „nativ“ in der Regel, dass die Anwendung direkt mit dem zugrunde liegenden Fenstersystem kommuniziert und keine Zwischenschicht verwendet. Qt-Anwendungen laufen als „First-Class-Citizens“, genau wie Cocoa-Anwendungen. Intern nutzen wir Cocoa für die Kommunikation mit dem Betriebssystem.
Warnungen zur Sichtbarkeit von Symbolen
Im Zusammenhang mit dem Verknüpfen von C++-Bibliotheken werden Funktionen und Objekte als Symbole bezeichnet. Symbole können entweder die Sichtbarkeit „ default “ oder „ hidden “ haben.
Aus Leistungsgründen kompilieren Qt und viele andere Bibliotheken ihre Quellcodes standardmäßig mit der Sichtbarkeit „ hidden “ und kennzeichnen Symbole erst dann mit der Sichtbarkeit „ default “, wenn sie für die Verwendung in Anwenderprojekten vorgesehen sind.
Leider kann der Apple-Linker Warnungen ausgeben, wenn eine Bibliothek mit der Sichtbarkeit „ hidden “ kompiliert wird und eine Anwendung oder Bibliothek eines Benutzerprojekts mit der Sichtbarkeit „ default “ kompiliert wird.
Wenn Projektentwickler die Warnung unterdrücken möchten, müssen sie ihren Projektcode ebenfalls mit der Sichtbarkeit „ hidden “ erstellen.
In CMake kann dies erreicht werden, indem der folgende Code in Ihre ` CMakeLists.txt` eingefügt wird:
set(CMAKE_CXX_VISIBILITY_PRESET hidden)In qmake kann dies durch Hinzufügen des folgenden Codes zu Ihrer ` .pro `-Datei erreicht werden:
CONFIG+=hide_symbolsFalls ein Projekt Bibliotheken erstellt, müssen alle Symbole in der Bibliothek, die in einer anderen Bibliothek oder Anwendung verwendet werden sollen, explizit mit der Sichtbarkeit „ default “ gekennzeichnet werden. Dies kann beispielsweise dadurch erfolgen, dass solche Funktionen oder Klassen mit „ Q_DECL_EXPORT “ versehen werden.
dSYM-Bundle fehlt im xcarchive, das von einem CMake-Xcode-Projekt erstellt wurde
Aufgrund eines Fehlers in Xcode und bestimmter CMake-Einschränkungen versäumt es ein von CMake generiertes Xcode-Projekt, das „ dSYM “-Bundle einer Anwendung während der Archivierungsaufgabe von Xcode in ein „ xcarchive “ einzubinden.
Qt bietet eine optionale Abhilfe an, damit das „ dSYM “-Bundle in das „ xcarchive “ aufgenommen wird, was jedoch mit Einschränkungen verbunden ist. Das heißt, die folgenden CMake-Funktionen funktionieren nicht korrekt:
$<TARGET_FILE:app>-Generatorausdrücke werden möglicherweise zu einem ungültigen Pfad erweitert, der nicht zur App-Binärdatei führt- Die Variable „
CMAKE_RUNTIME_OUTPUT_DIRECTORY“ und die zugehörige Ziel-Eigenschaft „RUNTIME_OUTPUT_DIRECTORY“ werden ignoriert, selbst wenn sie gesetzt sind - weitere unbekannte Probleme
Um die oben genannten Probleme zu beheben, können Sie Folgendes tun:
- Aktivieren Sie die Problemumgehung nur, wenn Sie die „
xcarchive“ erstellen möchten, und nicht während der Projektentwicklung - Stellen Sie sicher, dass Sie ausführbare Dateien und Bibliotheken nur im Stammverzeichnis des Projekts hinzufügen und nicht in Aufrufen von „
add_subdirectory“.
Um die Abhilfe zu aktivieren, konfigurieren Sie das Projekt mit der folgenden Option:
cmake . -DQT_USE_RISKY_DSYM_ARCHIVING_WORKAROUND=ONoder setzen Sie die Variable im Projekt vor allen Aufrufen von ` qt_add_executable ` oder ` qt_add_library `:
set(QT_USE_RISKY_DSYM_ARCHIVING_WORKAROUND ON)
...
qt_add_executable(app)© 2026 The Qt Company Ltd. Documentation contributions included herein are the copyrights of their respective owners. The documentation provided herein is licensed under the terms of the GNU Free Documentation License version 1.3 as published by the Free Software Foundation. Qt and respective logos are trademarks of The Qt Company Ltd. in Finland and/or other countries worldwide. All other trademarks are property of their respective owners.