Qt pour macOS - Problèmes spécifiques
Cette page décrit les principaux problèmes concernant le support de macOS dans Qt. La terminologie macOS et les processus spécifiques se trouvent à l'adresse https://developer.apple.com/.
Aqua
Le style Aqua est une partie essentielle de la plateforme macOS. Comme pour Cocoa, Qt fournit des widgets qui ressemblent à ceux décrits dans les lignes directrices de l'interface humaine de macOS. Notez que bien que les widgets de Qt utilisent AppKit sous le capot pour l'aspect et la convivialité, il ne représente pas chaque Qt Widgets individuel comme un contrôle natif enveloppé.
La page Qt Widgets Gallery contient des exemples d'images d'applications utilisant le thème de la plateforme macOS.
Attributs Qt pour macOS
La liste suivante énumère un ensemble d'attributs utiles qui peuvent être utilisés pour améliorer les applications sur macOS :
- 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 met toujours l'écran en double tampon, l'attribut Qt::WA_PaintOnScreen n'a donc aucun effet. Il est également impossible de peindre en dehors d'un événement de peinture, donc Qt::WA_PaintOutsidePaintEvent n'a pas d'effet non plus.
Clics droits de la souris
La classe QContextMenuEvent prend en charge le clic droit de la souris pour les applications macOS. Cela correspondra à un événement de menu contextuel, par exemple, un menu qui affichera une sélection contextuelle. Il s'agit de l'utilisation la plus courante du clic droit de la souris, qui correspond à un contrôle-clic avec le support de la souris à un bouton de macOS.
Internationalisation
Les applications sous macOS déclarent les langues prises en charge dans le cadre du site Info.plist de l'application. Le système fait alors correspondre les langues prises en charge par l'application avec les préférences linguistiques de l'utilisateur afin de déterminer les paramètres locaux dans lesquels l'application est lancée. Cela détermine à son tour les langues ordonnées reflétées par QLocale::uiLanguages(), et la façon dont les cadres du système tels que AppKit récupèrent leurs ressources localisées, telles que les titres de menu et les chaînes de caractères.
Comme les applications Qt XML ne sont pas traduites au départ, la valeur par défaut de Info.plist générée pour les projets CMake et qmake est de CFBundleAllowMixedLocalizations à YES, afin de permettre aux frameworks système de choisir la localisation qui correspond le mieux aux préférences linguistiques de l'utilisateur, même si cette localisation n'est pas disponible pour l'application elle-même. Une fois que vous avez ajouté des traductions à votre application via qt_add_translations, la clé CFBundleAllowMixedLocalizations sera automatiquement supprimée et remplacée par CFBundleLocalizationsqui énumère toutes les langues que vous prenez en charge. Pour qmake, ce processus doit être effectué manuellement.
Barre de menu
Qt détecte les barres de menu et les transforme en barres de menu natives pour Mac. L'intégration dans les applications Qt existantes est normalement automatique. Toutefois, si vous avez des besoins particuliers, l'implémentation de Qt sélectionne actuellement une barre de menu en commençant par la fenêtre active (par exemple, QGuiApplication::focusWindow()) et en appliquant les tests suivants :
- Si la fenêtre a un QMenuBar, elle est utilisée.
- Si la fenêtre est modale, sa barre de menu est utilisée. Si aucune barre de menu n'est spécifiée, une barre de menu par défaut est utilisée (comme documenté ci-dessous).
- Si la fenêtre n'a pas de parent, la barre de menu par défaut est utilisée (voir ci-dessous).
Ces tests sont effectués tout au long de la chaîne de fenêtres parentales jusqu'à ce que l'une des règles ci-dessus soit respectée. En cas d'échec, une barre de menu par défaut est créée. La barre de menu par défaut de Qt est une barre de menu vide. Cependant, vous pouvez créer une barre de menu par défaut différente en créant une fenêtre sans parent QMenuBar. La première barre de menu créée sera désignée comme barre de menu par défaut et sera utilisée chaque fois qu'une barre de menu par défaut sera nécessaire.
L'utilisation de barres de menu natives introduit certaines limitations sur les classes Qt. La section avec la liste des limitations ci-dessous contient plus d'informations.
Qt prend en charge la barre de menu globale avec QMenuBar. Les utilisateurs de macOS s'attendent à avoir une barre de menu en haut de l'écran et Qt honore cela.
De plus, les utilisateurs s'attendent à ce que certaines conventions soient respectées, par exemple le menu de l'application devrait contenir A propos de, Préférences, Quitter, et ainsi de suite. Qt gère ces conventions, bien qu'il ne fournisse pas de moyen d'interagir directement avec le menu de l'application.
Chaque site QAction possède une propriété menuRole qui contrôle l'emplacement spécial des éléments du menu d'application ; cependant, par défaut, la propriété menuRole est TextHeuristicRole, ce qui signifie que les éléments du menu seront détectés automatiquement par leur text.
D'autres éléments de menu standard tels que Couper, Copier, Coller et Sélectionner tout sont applicables à la fois dans votre application et dans certaines boîtes de dialogue natives telles que QFileDialog. Il est important que vous créiez ces éléments de menu avec les raccourcis standard afin que les fonctions d'édition correspondantes soient activées dans les boîtes de dialogue. Pour l'instant, il n'existe pas d'identifiant MenuRole pour ces éléments, mais ils seront détectés automatiquement comme les éléments de menu de l'application lorsque le site QAction a la valeur par défaut TextHeuristicRole.
Touches spéciales
Afin de fournir le comportement attendu pour les applications Qt XML sur macOS, les valeurs de l'énumération Qt::Key_Meta, Qt::MetaModifier, et Qt::META correspondent aux touches Contrôle du clavier Apple standard, et les valeurs de l'énumération Qt::Key_Control, Qt::ControlModifier, et Qt::CTRL correspondent aux touches Commande.
Station d'accueil
Il est possible d'interagir avec le dock. L'icône peut être définie en appelant QWindow::setIcon() à partir de la fenêtre principale de votre application. L'appel à setIcon() peut être effectué aussi souvent que nécessaire, ce qui permet d'obtenir une icône qui peut être facilement mise à jour.
Accessibilité
De nombreux utilisateurs utilisent macOS avec des dispositifs d'assistance. Avec Qt, l'objectif est de rendre cela automatique dans votre application afin qu'elle soit conforme aux pratiques acceptées sur sa plateforme. Qt utilise le cadre d'accessibilité d'Apple pour fournir un accès aux utilisateurs handicapés.
Bibliothèque et support de déploiement
Qt prend en charge les structures macOS telles que les Frameworks et les bundles. Il est important de connaître ces structures car elles affectent directement le déploiement des applications.
Qt fournit un outil de déploiement, macdeployqt, pour simplifier le processus de déploiement. L'article Qt pour macOS - Déploiement couvre le processus de déploiement de manière plus détaillée.
Les bibliothèques Qt en tant que frameworks
Par défaut, Qt est construit comme un ensemble de frameworks. Les frameworks sont le moyen préféré de macOS pour distribuer les bibliothèques. Le site Apple's Framework Programming Guide contient beaucoup plus d'informations sur les frameworks.
Il est important de se rappeler que les Frameworks sont toujours liés aux versions release des bibliothèques. Si la version de débogage d'un framework Qt XML est souhaitée, utilisez les variables d'environnement DYLD_IMAGE_SUFFIX pour vous assurer que la version de débogage est chargée :
export DYLD_IMAGE_SUFFIX=_debug
Vous pouvez également échanger temporairement vos versions de débogage et de publication, ce qui est décrit dans la note technique "Debugging Magic" d'Apple.
Si vous ne souhaitez pas utiliser de frameworks, configurez simplement Qt XML avec -no-framework.
./configure -no-framework
Bibliothèques basées sur des paquets
Si vous souhaitez utiliser des bibliothèques dynamiques dans le bundle de macOS (le répertoire de l'application), créez un sous-répertoire nommé Frameworks dans le répertoire du bundle de l'application et placez-y vos bibliothèques dynamiques. L'application trouvera une bibliothèque dynamique si elle porte le nom d'installation @executable_path/../Frameworks/libname.dylib.
Si vous utilisez qmake et Makefiles, utilisez le paramètre QMAKE_LFLAGS_SONAME:
QMAKE_LFLAGS_SONAME = -Wl,-install_name,@executable_path/../Frameworks/
Vous pouvez également modifier le nom d'installation à l'aide de install_name_tool(1) sur la ligne de commande.
La variable d'environnement DYLD_LIBRARY_PATH remplacera ces paramètres, ainsi que tout autre chemin par défaut, comme la recherche de bibliothèques dynamiques dans /usr/lib et d'autres emplacements par défaut similaires.
Combinaison de bibliothèques
Si vous souhaitez construire une nouvelle bibliothèque dynamique combinant les bibliothèques dynamiques de Qt, vous devez introduire le drapeau ld -r. Les informations de relocalisation sont alors stockées dans le fichier de sortie, de sorte que ce fichier puisse faire l'objet d'une autre exécution de ld. Pour ce faire, vous devez définir l'indicateur -r dans le fichier .pro et les paramètres LFLAGS.
Ordre d'initialisation
dyld(1) appelle les initialisateurs statiques globaux dans l'ordre dans lequel ils sont liés à l'application. Si une bibliothèque est liée à Qt et fait référence aux globaux de Qt (à partir des initialisateurs globaux de votre propre bibliothèque), liez l'application à Qt avant de la lier à la bibliothèque. Sinon, le résultat sera indéfini car les initialisateurs globaux de Qt n'ont pas encore été appelés.
Indicateurs de compilation
Les drapeaux suivants sont utiles lorsque vous souhaitez définir du code spécifique à macOS :
Q_OS_DARWINest défini lorsque Qt détecte que vous êtes sur un système basé sur Darwin tel que macOS ou iOS.Q_OS_MACOSest défini lorsque vous êtes sur un système macOS.
Note : Q_WS_MAC n'est plus défini dans Qt 5 et les versions ultérieures.
Si vous voulez définir du code pour des versions spécifiques de macOS, utilisez les macros de disponibilité définies dans /usr/include/AvailabilityMacros.h.
La documentation de QSysInfo et de QOperatingSystemVerison contient des informations sur la vérification de la version au moment de l'exécution.
Accès à l'API native de macOS
Accès au chemin de l'offre groupée
Les applications macOS sont structurées comme un répertoire (se terminant par .app). Ce répertoire contient des sous-répertoires et des fichiers. Il peut être utile de placer des éléments, tels que des plugins et de la documentation en ligne, à l'intérieur de ce paquet. Le code suivant renvoie le chemin d'accès au paquet d'applications :
#ifdef Q_OS_MAC QString bundlePath = QString::fromNSString(NSBundle.mainBundle.bundlePath) ; qDebug() << "Bundle path =" << bundlePath; #endif
Pour plus d'informations sur l'utilisation de l'API NSBundle, visitez le site Web des développeurs d'Apple.
QCoreApplication::applicationDirPath() peut être utilisé pour déterminer le chemin du binaire dans le bundle.
Utilisation de panneaux Cocoa natifs
Le distributeur d'événements de Qt est plus flexible que ce qu'offre Cocoa, et permet à l'utilisateur de faire tourner le distributeur d'événements (et d'exécuter QEventLoop::exec) sans avoir à se demander si des boîtes de dialogue modales s'affichent ou non à l'écran (ce qui est une différence par rapport à Cocoa). Par conséquent, nous devons effectuer une gestion supplémentaire dans Qt pour gérer cela correctement, ce qui rend malheureusement difficile le mélange de panneaux natifs. La meilleure façon de procéder pour le moment est de suivre le modèle ci-dessous, où nous postons l'appel à la fonction avec du code natif plutôt que de l'appeler directement. Nous savons alors que Qt a proprement mis à jour toutes les récursions de boucle d'événements en attente avant que le panneau natif ne soit affiché :
#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(); }
Limites
MySQL et macOS
Il semble y avoir un problème lorsque -prebind et -multi_module sont tous deux définis lors de l'édition de liens entre des bibliothèques C statiques et des bibliothèques dynamiques. Si vous obtenez le message d'erreur suivant lors de l'édition de liens avec Qt :
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 failed
ré-enchaîner Qt en utilisant -single_module. Ce problème ne se pose que lors de l'intégration du pilote MySQL dans Qt. Il n'affecte pas les plugins ou les constructions statiques.
D-Bus et macOS
Le module QtDBus charge par défaut la bibliothèque libdbus-1 sur macOS. Cela signifie que les applications liant le module QtDBus se chargeront même sur les systèmes macOS qui n'ont pas les bibliothèques, mais qu'elles ne parviendront pas à se connecter à un serveur D-Bus ni à ouvrir un serveur utilisant QDBusServer.
Pour utiliser la fonctionnalité D-Bus, vous devez installer la bibliothèque libdbus-1, par exemple via Homebrew, Fink ou MacPorts. Vous pouvez inclure ces bibliothèques dans le paquet de votre application si vous la déployez sur d'autres systèmes. De plus, notez qu'il n'y a pas de bus système sur macOS et que le bus de session ne sera démarré qu'après que launchd ait été configuré pour le gérer.
Actions du menu
- Les actions dans un QMenu avec des accélérateurs qui ont plus d'une touche (QKeySequence) ne s'affichent pas correctement lorsque le QMenu est traduit en une barre de menu native Mac. La première touche sera affichée. Toutefois, le raccourci sera toujours activé comme sur toutes les autres plateformes.
- QMenu Les objets utilisés dans la barre de menu native ne peuvent pas gérer les événements Qt via les gestionnaires d'événements normaux. Installez un délégué sur le menu lui-même pour être informé de ces changements. Vous pouvez également utiliser les signaux QMenu::aboutToShow() et QMenu::aboutToHide() pour suivre la visibilité du menu ; ils fournissent une solution qui devrait fonctionner sur toutes les plates-formes prises en charge par Qt.
- Par défaut, Qt crée un élément de menu Quit natif qui réagit au raccourci
CMD+Q. La création d'un QAction pour le rôle QAction::QuitRole remplacera cet élément de menu. Par conséquent, l'action de remplacement doit être connectée soit au slot QCoreApplication::quit, soit à un slot personnalisé qui arrête l'application.
Widgets natifs
Qt prend en charge les feuilles, représentées par le drapeau de fenêtre, Qt::Sheet.
En général, lorsqu'on parle d'une application macOS native, on entend par native une application qui s'interface directement avec le système de fenêtres sous-jacent, plutôt qu'une application qui utilise une couche intermédiaire. Les applications Qt fonctionnent comme des citoyens de première classe, tout comme les applications Cocoa. Nous utilisons Cocoa en interne pour communiquer avec le système d'exploitation.
Avertissements sur la visibilité des symboles
Dans le contexte de la liaison des bibliothèques C++, les fonctions et les objets sont appelés symboles. Les symboles peuvent avoir une visibilité de default ou de hidden.
Pour des raisons de performance, Qt XML et de nombreuses autres bibliothèques compilent leurs sources en utilisant par défaut la visibilité hidden, et ne marquent les symboles avec la visibilité default que lorsqu'ils sont destinés à être utilisés dans des projets d'utilisateurs.
Malheureusement, l'éditeur de liens d'Apple peut émettre des avertissements lorsqu'une bibliothèque est compilée avec la visibilité hidden et qu'une application ou une bibliothèque d'un projet d'utilisateur est compilée avec la visibilité default.
Si les développeurs de projets veulent faire taire l'avertissement, ils doivent également compiler le code de leur projet avec la visibilité hidden.
Dans CMake, cela peut être fait en ajoutant le code suivant à votre fichier CMakeLists.txt:
set(CMAKE_CXX_VISIBILITY_PRESET hidden)
Dans qmake, cela peut être fait en ajoutant le code suivant à votre fichier .pro:
CONFIG+=hide_symbols
Si un projet construit des bibliothèques, tous les symboles de la bibliothèque qui sont destinés à être utilisés dans une autre bibliothèque ou application devront être explicitement marqués avec la visibilité default. Par exemple, cela peut être fait en annotant ces fonctions ou classes avec Q_DECL_EXPORT.
bundle dSYM manquant dans xcarchive créé par un projet CMake Xcode
En raison d'un bogue dans Xcode et de certaines limitations de CMake, un projet Xcode généré par CMake ne parvient pas à inclure le bundle dSYM d'une application dans une archive xcarchive, au cours de la tâche d'archivage de Xcode.
Qt XML fournit une solution de contournement sous forme d'opt-in, de sorte que le bundle dSYM est inclus dans le xcarchive, mais elle s'accompagne de compromis. En effet, les fonctionnalités CMake suivantes ne fonctionneront pas correctement :
- toutes les expressions du générateur
$<TARGET_FILE:app>peuvent se développer en un chemin invalide qui ne mène pas au binaire de l'application - la variable
CMAKE_RUNTIME_OUTPUT_DIRECTORYet la propriétéRUNTIME_OUTPUT_DIRECTORYtarget qui lui est associée seront ignorées même si elles sont définies. - autres problèmes inconnus
Pour atténuer les problèmes susmentionnés, vous pouvez :
- n'activer la solution de contournement que lorsque vous avez l'intention de créer le site
xcarchiveet non pendant le développement du projet - vous assurer que vous n'ajoutez des exécutables et des bibliothèques que dans le répertoire racine du projet, et non dans les appels
add_subdirectory.
Pour activer la solution de contournement, configurez le projet avec l'option suivante :
cmake . -DQT_USE_RISKY_DSYM_ARCHIVING_WORKAROUND=ON
ou définissez la variable dans le projet avant tout appel à qt_add_executable ou 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.