<qqmlintegration.h>
| Header: | #include <QtQmlIntegration/qqmlintegration.h> |
Macros
| QML_ADDED_IN_VERSION(MAJOR, MINOR) | |
| QML_ANONYMOUS | |
| QML_ATTACHED(ATTACHED_TYPE) | |
(since 6.5) | QML_CONSTRUCTIBLE_VALUE |
| QML_ELEMENT | |
| QML_EXTENDED(EXTENDED_TYPE) | |
| QML_EXTENDED_NAMESPACE(EXTENSION_NAMESPACE) | |
| QML_EXTRA_VERSION(MAJOR, MINOR) | |
| QML_FOREIGN(FOREIGN_TYPE) | |
| QML_FOREIGN_NAMESPACE(FOREIGN_NAMESPACE) | |
| QML_IMPLEMENTS_INTERFACES(interfaces) | |
| QML_INTERFACE | |
| QML_NAMED_ELEMENT(name) | |
| QML_REMOVED_IN_VERSION(MAJOR, MINOR) | |
| QML_SEQUENTIAL_CONTAINER(VALUE_TYPE) | |
| QML_SINGLETON | |
(since 6.5) | QML_STRUCTURED_VALUE |
| QML_UNAVAILABLE | |
| QML_UNCREATABLE(reason) | |
| QML_VALUE_TYPE(name) |
Description détaillée
Cet en-tête fournit des macros permettant d'enregistrer des types C++ dans QML.
Voir également qt_generate_foreign_qml_types(), Présentation - Intégration de QML et C++, et qmltyperegistrar.
Documentation des macros
QML_ADDED_IN_VERSION(MAJOR, MINOR)
Indique que le type ou l'espace de noms englobant a été ajouté dans la version spécifiée de MAJOR.MINOR. La version est supposée correspondre aux révisions indiquées par les macros Q_REVISION() sur les méthodes, les slots ou les signaux, ainsi qu'aux attributs REVISION() sur les propriétés déclarées avec Q_PROPERTY().
QML_ADDED_IN_VERSION() ne prend effet que si le type ou l’espace de noms est disponible en QML, c’est-à-dire s’il dispose d’une macro QML_ELEMENT, QML_NAMED_ELEMENT(), QML_ANONYMOUS ou QML_INTERFACE.
Si le module QML auquel appartient le type est importé avec une version inférieure à celle ainsi déterminée, le type QML est invisible.
Voir également QML_ELEMENT et QML_NAMED_ELEMENT.
QML_ANONYMOUS
Indique que le type d'encapsulation est disponible, mais anonyme en QML. Ce type ne peut être ni créé ni utilisé pour déclarer des propriétés en QML, mais il est reconnu lorsqu'il est transmis depuis le C++. En QML, vous pouvez utiliser les propriétés de ce type si elles sont déclarées en C++.
Voir également QML_ELEMENT, QML_NAMED_ELEMENT(), QML_UNCREATABLE() et QML_INTERFACE.
QML_ATTACHED(ATTACHED_TYPE)
Indique que le type englobant associe « ATTACHED_TYPE » en tant que propriété attachée à d’autres types. Cela s’applique si le type est exposé à QML à l’aide d’une macro « QML_ELEMENT » ou « QML_NAMED_ELEMENT() ».
Remarque : le nom de la classe doit être entièrement qualifié, même si vous vous trouvez déjà dans l'espace de noms.
Voir également QML_ELEMENT, QML_NAMED_ELEMENT(), qmlAttachedPropertiesObject() et Fourniture de propriétés associées.
[since 6.5] QML_CONSTRUCTIBLE_VALUE
Indique que le type de valeur associé est constructible. Autrement dit, tous les constructeurs Q_INVOKABLE de ce type qui prennent exactement un argument peuvent être utilisés lors de l'affectation d'une valeur JavaScript à une propriété de ce type.
Vous pouvez déclarer un type de valeur constructible comme suit :
class MyValueType
{
Q_GADGET
QML_VALUE_TYPE(myValueType)
QML_CONSTRUCTIBLE_VALUE
public:
Q_INVOKABLE MyValueType(double d);
// ...
};Avec le type ci-dessus, le code QML suivant produira une valeur d'MyValueType s à l'aide du constructeur donné et l'attribuera à la propriété.
QtObject {
property myValueType v: 5.4
}Vous pouvez également construire des listes de valeurs de cette manière :
QtObject {
property list<myValueType> v: [5.4, 4.5, 3.3]
}Depuis Qt 6.8, si vous importez le module QML auquel appartient le type de valeur dans un espace de noms, vous pouvez utiliser l’opérateur ` new ` de JavaScript pour l’instancier.
import MyModule as MM
QtObject {
function process(d: real) {
let v = new MM.myValueType(d);
// v is a myValueType now
}
}Cette macro a été introduite dans Qt 6.5.
Voir également QML_VALUE_TYPE.
QML_ELEMENT
Déclare que le type ou l'espace de noms englobant est disponible dans QML, en utilisant le nom de sa classe ou de son espace de noms comme nom d'élément QML.
Par exemple, cela rend la classe C++ Slider disponible en tant que type QML nommé Slider. Toutes ses propriétés, méthodes appelables et énumérations sont exposées.
class Slider : public QObject
{
Q_OBJECT
QML_ELEMENT
Q_PROPERTY(int value READ value WRITE setValue NOTIFY valueChanged FINAL)
// ...
public:
enum Slippiness {
Dry, Wet, Icy
};
Q_ENUM(Slippiness)
Q_INVOKABLE void slide(Slippiness slippiness);
// ...
}Vous pouvez utiliser le système de construction pour enregistrer le type dans l’espace de noms de types `com.mycompany.qmlcomponents ` avec la version majeure ` 1`. Pour `qmake`, spécifiez ce qui suit dans votre fichier de projet :
CONFIG += qmltypes
QML_IMPORT_NAME = com.mycompany.qmlcomponents
QML_IMPORT_MAJOR_VERSION = 1Avec CMake, vous transmettez l’URI et la version à la fonction ` qt_add_qml_module()`
qt_add_qml_module(myapp
URI com.mycompany.qmlcomponents
VERSION 1.0
)Une fois enregistré, le type peut être utilisé en QML en important le même espace de noms de type et le même numéro de version :
import com.mycompany.qmlcomponents 1.0
Slider {
value: 12
Component.onCompleted: slide(Slider.Icy)
// ...
}Vous pouvez également rendre disponibles de cette manière les espaces de noms marqués de l’ Q_NAMESPACE, afin d’exposer toutes les énumérations marquées de l’ Q_ENUM_NS qu’ils contiennent :
namespace MyNamespace {
Q_NAMESPACE
QML_ELEMENT
enum MyEnum {
Key1,
Key2,
};
Q_ENUM_NS(MyEnum)
}Dans QML, vous pouvez alors utiliser ces énumérations :
Component.onCompleted: console.log(MyNamespace.Key2)REMARQUE : lorsque des classes portent le même nom mais se trouvent dans des espaces de noms différents, l'utilisation de QML_ELEMENT sur les deux entraînera un conflit. Veillez à utiliser QML_NAMED_ELEMENT() pour l'une d'entre elles à la place.
Remarque : le nom de la classe doit être entièrement qualifié, même si vous vous trouvez déjà dans l’espace de noms.
Voir également « Choisir la bonne méthode d’intégration entre C++ et QML », QML_NAMED_ELEMENT(), Q_REVISION() et QML_ADDED_IN_VERSION().
QML_EXTENDED(EXTENDED_TYPE)
Déclare que le type englobant utilise EXTENDED_TYPE comme extension afin de fournir des propriétés, des méthodes et des énumérations supplémentaires dans QML. Cela prend effet si le type est exposé à QML à l'aide d'une macro QML_ELEMENT ou QML_NAMED_ELEMENT().
Avertissement : les membres de EXTENDED_TYPE sont implicitement traités comme FINAL.
Remarque : le nom de la classe doit être entièrement qualifié, même si vous vous trouvez déjà dans l'espace de noms.
Voir également QML_ELEMENT, QML_NAMED_ELEMENT(), QML_EXTENDED_NAMESPACE() et Enregistrement d’objets d’extension.
QML_EXTENDED_NAMESPACE(EXTENSION_NAMESPACE)
Déclare que le type englobant utilise EXTENSION_NAMESPACE comme extension afin de fournir des énumérations supplémentaires dans QML. Cela prend effet si le type est exposé à QML à l'aide d'une macro QML_ELEMENT ou QML_NAMED_ELEMENT(). Pour que cela fonctionne, les énumérations doivent être exposées au système de méta-objets.
Prenons par exemple le code C++ suivant
namespace MyNamespace {
Q_NAMESPACE
enum MyEnum { MyEnumerator = 10 };
Q_ENUM_NS(MyEnum)
}
class QmlType : public QObject
{
Q_OBJECT
QML_ELEMENT
QML_EXTENDED_NAMESPACE(MyNamespace)
}nous pouvons accéder à l’énumération dans QML :
QmlType {
property int i: QmlType.MyEnumerator // i will be 10
}Remarque : ` EXTENSION_NAMESPACE ` peut également être un ` QObject ` ou un `QGadget` ; dans ce cas — et contrairement à ` QML_EXTENDED`, qui expose également des méthodes et des propriétés — seules ses énumérations sont exposées.
Remarque : EXTENSION_NAMESPACE doit disposer d’un méta-objet ; c’est-à-dire qu’il doit s’agir soit d’un espace de noms contenant la macro Q_NAMESPACE, soit d’un QObject/ QGadget.
Remarque : le nom de la classe doit être entièrement qualifié, même si vous vous trouvez déjà à l'intérieur de l'espace de noms.
Voir également QML_NAMESPACE_EXTENDED(), QML_ELEMENT, QML_NAMED_ELEMENT(), QML_EXTENDED(), Enregistrement d’objets d’extension, Q_ENUM et Q_ENUM_NS.
QML_EXTRA_VERSION(MAJOR, MINOR)
Indiquez que le type doit également être disponible dans les versions MAJOR etMINOR. Cela peut s'avérer utile si un type doit être disponible dans plusieurs versions majeures.
Les types sont automatiquement enregistrés pour :
- La version majeure dans laquelle ils ont été introduits, voir QML_ADDED_IN_VERSION.
- Toutes les versions majeures dans lesquelles leurs membres ont été introduits.
- La version majeure actuelle de leur module, à moins qu’ils n’aient été QML_REMOVED_IN_VERSION avant cela.
Il est à noter qu’ils ne sont pas automatiquement enregistrés dans les versions PAST_MAJOR_VERSIONS situées entre celles mentionnées ci-dessus. Vous pouvez utiliser QML_EXTRA_VERSION pour enregistrer manuellement vos types dans d’autres versions majeures.
Remarque : la gestion de plusieurs PAST_MAJOR_VERSIONS est coûteuse en termes de calcul.
Voir également QML_ELEMENT et QML_ADDED_IN_VERSION.
QML_FOREIGN(FOREIGN_TYPE)
Spécifie que les macros QML_ELEMENT, QML_NAMED_ELEMENT(), QML_ANONYMOUS, QML_INTERFACE, QML_UNCREATABLE(), QML_SINGLETON, QML_ADDED_IN_VERSION(), QML_REMOVED_IN_VERSION(), QML_ADDED_IN_MINOR_VERSION(), QML_REMOVED_IN_MINOR_VERSION(), QML_EXTENDED(), QML_EXTENDED_NAMESPACE() ou QML_NAMESPACE_EXTENDED() présentes dans le type C++ englobant ne s’appliquent pas à ce type, mais à FOREIGN_TYPE. Le type englobant doit tout de même être enregistré auprès du système de méta-objets à l’aide d’une macro Q_GADGET ou Q_OBJECT.
Ceci est utile pour enregistrer des types qui ne peuvent pas être modifiés pour y ajouter les macros, par exemple parce qu’ils appartiennent à des bibliothèques tierces. Pour enregistrer un espace de noms, voir QML_FOREIGN_NAMESPACE().
Remarque : vous pouvez préférer utiliser ` QML_NAMED_ELEMENT()` plutôt que ` QML_ELEMENT`. Avec ` QML_ELEMENT`, l’élément est nommé d’après la structure dans laquelle il est contenu, et non d’après le type étranger. Le chapitre « Intégration d’objets étrangers » de la documentation « Écriture d’extensions QML avancées avec C++ » illustre ce principe.
Remarque : QML_ATTACHED() ne peut actuellement pas être redirigé de cette manière. Il doit être spécifié dans le même type que celui qui implémente qmlAttachedProperties().
Remarque : le nom de la classe doit être entièrement qualifié, même si vous vous trouvez déjà dans l’espace de noms.
Voir également QML_ELEMENT, QML_NAMED_ELEMENT() et QML_FOREIGN_NAMESPACE().
QML_FOREIGN_NAMESPACE(FOREIGN_NAMESPACE)
Déclare que toutes les macros QML_ELEMENT, QML_NAMED_ELEMENT(), QML_ANONYMOUS, QML_INTERFACE, QML_UNCREATABLE(), QML_SINGLETON, QML_ADDED_IN_VERSION(), QML_REMOVED_IN_VERSION(), QML_ADDED_IN_MINOR_VERSION() ou QML_REMOVED_IN_MINOR_VERSION() présentes dans l'espace de noms C++ englobant ne s'appliquent pas au type englobant, mais à FOREIGN_NAMESPACE. L'espace de noms englobant doit tout de même être enregistré auprès du système de méta-objets à l'aide d'une macro Q_NAMESPACE.
Ceci est utile pour enregistrer des espaces de noms qui ne peuvent pas être modifiés pour y ajouter les macros, par exemple parce qu’ils appartiennent à des bibliothèques tierces.
Voir également QML_ELEMENT, QML_NAMED_ELEMENT() et QML_FOREIGN().
QML_IMPLEMENTS_INTERFACES(interfaces)
Cette macro indique à Qt quelle interfaces QML la classe implémente. Elle ne doit être utilisée que pour l'interfaçage avec des classes utilisant QML_INTERFACE; dans le cas contraire, utilisez Q_INTERFACES. Elle est nécessaire au bon fonctionnement de l'enregistrement déclaratif via QML_ELEMENT.
Voir également QML_INTERFACE et Q_INTERFACES.
QML_INTERFACE
Cette macro enregistre le type C++ contenant dans le système QML en tant qu'interface.
Les types enregistrés en tant qu'interface dans QML doivent également se déclarer comme interface auprès du système de méta-objets. Par exemple :
struct FooInterface
{
QML_INTERFACE
public:
virtual ~FooInterface();
virtual void doSomething() = 0;
};
Q_DECLARE_INTERFACE(FooInterface, "org.foo.FooInterface")Lorsqu'ils sont enregistrés de cette manière dans QML, ils peuvent être utilisés comme types de propriétés :
Q_PROPERTY(FooInterface *foo READ foo WRITE setFoo)
Lorsque vous attribuez une sous-classe de « QObject » à cette propriété, le moteur QML effectue automatiquement la conversion d’interface vers « FooInterface* ».
Les types d’interface sont implicitement anonymes et ne peuvent pas être créés en QML.
REMARQUE : lorsque vous héritez de types utilisant QML_INTERFACE, utilisez QML_IMPLEMENTS_INTERFACES au lieu de Q_INTERFACES.
Voir également QML_IMPLEMENTS_INTERFACES(), QML_ELEMENT, QML_NAMED_ELEMENT(), QML_UNCREATABLE() et QML_ANONYMOUS.
QML_NAMED_ELEMENT(name)
Déclare que le type ou l'espace de noms englobant est disponible dans QML, en utilisant name comme nom d'élément. Sinon, son comportement est identique à celui de QML_ELEMENT.
class SqlEventDatabase : public QObject
{
Q_OBJECT
QML_NAMED_ELEMENT(EventDatabase)
// ...
};Voir également «Choisir la bonne méthode d'intégration entre C++ et QML » et « QML_ELEMENT ».
QML_REMOVED_IN_VERSION(MAJOR, MINOR)
Indique que le type ou l’espace de noms englobant a été supprimé dans la version spécifiée de MAJOR.MINOR. Cela s’avère particulièrement utile lors du remplacement de l’implémentation d’un type QML. Si une fonction QML_ADDED_IN_VERSION() correspondante est présente sur un autre type ou espace de noms portant le même nom QML, alors le type supprimé est utilisé lors de l’importation de versions du module antérieures à MAJOR.MINOR, et le type ajouté est utilisé lors de l’importation de versions du module supérieures ou égales à MAJOR.MINOR.
QML_REMOVED_IN_VERSION() ne prend effet que si le type ou l'espace de noms est disponible en QML, via une macro QML_ELEMENT, QML_NAMED_ELEMENT(), QML_ANONYMOUS ou QML_INTERFACE.
Voir également QML_ELEMENT et QML_NAMED_ELEMENT.
QML_SEQUENTIAL_CONTAINER(VALUE_TYPE)
Cette macro déclare le type englobant ou référencé comme un conteneur séquentiel gérant une séquence d'éléments de type ` VALUE_TYPE `. ` VALUE_TYPE ` peut être un type de valeur proprement dit ou un pointeur vers un type d'objet. Vous aurez rarement la possibilité d'ajouter cette macro à la déclaration du conteneur proprement dite, car les conteneurs sont généralement des modèles. Vous devez utiliser ` QML_FOREIGN ` pour associer l’enregistrement du type à une instanciation de modèle. Grâce à cette technique, vous pouvez, par exemple, déclarer des conteneurs séquentiels comme suit :
class IntDequeRegistration
{
Q_GADGET
QML_FOREIGN(std::deque<int>)
QML_ANONYMOUS
QML_SEQUENTIAL_CONTAINER(int)
};Vous pouvez ensuite utiliser le conteneur comme un tableau JavaScript dans QML.
class Maze
{
Q_OBJECT
Q_ELEMENT
// 0: North, 1: East, 2: South, 3: West
Q_PROPERTY(std::deque<int> solution READ solution CONSTANT FINAL)
[...]
}Item {
Maze {
id: maze
}
function showSolution() {
maze.solution.forEach([...])
}
}Remarque : pour les types de valeurs QML, ` QList ` est automatiquement enregistré en tant que conteneur séquentiel. Pour les types d'objets QML, c'est ` QQmlListProperty ` qui l'est. Vous n'avez pas besoin d'ajouter ces enregistrements.
Remarque : vous ne pouvez actuellement pas attribuer de nom personnalisé au conteneur. Tout argument passé à QML_NAMED_ELEMENT est ignoré. Les conteneurs séquentiels enregistrés automatiquement sont disponibles sous les noms habituels de type list<...>, par exemple list<QtObject> ou list<font>.
Remarque : le nom de la classe doit être entièrement qualifié, même si vous vous trouvez déjà dans l'espace de noms.
Voir également QML_ANONYMOUS et QML_FOREIGN().
QML_SINGLETON
Déclare que le type englobant est un singleton dans QML. Cela ne prend effet que si le type est une « Q_OBJECT » et s’il est disponible dans QML (c’est-à-dire s’il dispose d’une macro « QML_ELEMENT » ou « QML_NAMED_ELEMENT() »). À moins que le type ne soit explicitement marqué comme « uncreatable » (non créable) à l’aide de la macro QML_UNCREATABLE(), chaque QQmlEngine tentera de créer une instance singleton en utilisant soit le constructeur par défaut du type, soit une fonction de fabrique statique de signature T *create(QQmlEngine *, QJSEngine *) lors du premier accès au type. Si les deux existent et sont accessibles, le constructeur par défaut est privilégié.
S’il n’y a ni constructeur par défaut ni fonction de création, et qu’aucune instance n’a été explicitement définie sur le moteur à l’aide de ` QQmlEngine::setExternalSingletonInstance `, le singleton est inaccessible. Si le moteur QML a instancié le singleton, il en assume généralement la propriété et le supprimera lorsque le moteur lui-même sera détruit. En revanche, le moteur ne prend pas en charge les singletons externes, sauf instruction explicite en ce sens. Vous pouvez contrôler ce comportement en appelant ` QJSEngine::setObjectOwnership()` sur le singleton afin de spécifier explicitement le comportement souhaité.
Pour déclarer une classe constructible par défaut comme singleton, il suffit d’ajouter QML_SINGLETON:
class MySingleton : public QObject
{
Q_OBJECT
QML_ELEMENT
QML_SINGLETON
// Q_PROPERTY( ... )
public:
// members, Q_INVOKABLE functions, etc.
};Si la classe singleton n’est pas constructible par défaut, mais que vous pouvez la modifier, vous pouvez lui ajouter une fonction de fabrique afin de la rendre accessible :
class MySingleton : public QObject
{
Q_OBJECT
QML_ELEMENT
QML_SINGLETON
// Q_PROPERTY( ... )
public:
static MySingleton *create(QQmlEngine *qmlEngine, QJSEngine *jsEngine)
{
MySingleton *result = nullptr;
// Create the object using some custom constructor or factory.
// The QML engine will assume ownership and delete it, eventually.
return result;
}
// members, Q_INVOKABLE functions, etc
};Si vous souhaitez fournir une instance au moteur plutôt que de laisser celui-ci l’instancier en cas de besoin, vous pouvez utiliser la macro ` QML_UNCREATABLE()`. Dans ce cas, le type n’a pas besoin d’être constructible par défaut ni de disposer d’une fonction de fabrique :
class MySingleton : public QObject
{
Q_OBJECT
QML_ELEMENT
QML_SINGLETON
QML_UNCREATABLE("Provided by C++")
// Q_PROPERTY( ... )
public:
MySingleton(BackendObject* backend, QObject* parent);
// members, Q_INVOKABLE functions, etc
};Cela nécessite qu’une instance de ` MySingleton ` soit définie sur le moteur à l’aide de ` QQmlEngine::setExternalSingletonInstance() ` avant que le singleton ne soit accédé pour la première fois depuis QML. Cela remplace la fonction ` qmlRegisterSingletonInstance `.
Si vous ne pouvez pas modifier la classe et qu’elle ne dispose pas d’un constructeur par défaut ou d’une fonction de création appropriée, vous pouvez fournir un wrapper QML_FOREIGN pour définir la fonction de création :
struct SingletonForeign
{
Q_GADGET
QML_FOREIGN(MySingleton)
QML_SINGLETON
QML_NAMED_ELEMENT(MySingleton)
public:
static MySingleton *create(QQmlEngine *, QJSEngine *engine)
{
MySingleton *result = nullptr;
// Create the instance using some custom constructor or factory.
// The QML engine will assume ownership and delete it, eventually.
return result;
}
};L’approche par ` QML_FOREIGN ` pour déclarer un singleton que vous ne pouvez pas modifier fonctionne également en combinaison avec ` QML_UNCREATABLE()`. Aucune fonction de fabrication n’est alors nécessaire, mais comme précédemment, l’instance doit être définie dans le moteur avant sa première utilisation :
struct SingletonForeign
{
Q_GADGET
QML_FOREIGN(MySingleton)
QML_SINGLETON
QML_NAMED_ELEMENT(MySingleton)
QML_UNCREATABLE("Provided from C++")
};Voir également QML_ELEMENT, QML_NAMED_ELEMENT(), qmlRegisterSingletonInstance(), QQmlEngine::singletonInstance(), QQmlEngine::setExternalSingletonInstance() et les singletons dans QML.
[since 6.5] QML_STRUCTURED_VALUE
Indique que le type de valeur associé est structuré. Les types de valeur structurés peuvent être, et seront de préférence, construits propriété par propriété à partir d’un objet JavaScript. Un type de valeur structuré est toutefois toujours également de type « QML_CONSTRUCTIBLE_VALUE ». Cela signifie que vous pouvez toujours fournir des constructeurs de type « Q_INVOKABLE » afin de gérer la construction à partir de types primitifs.
Vous pouvez déclarer un type de valeur structuré comme suit :
class MyValueType
{
Q_GADGET
QML_VALUE_TYPE(myValueType)
QML_STRUCTURED_VALUE
Q_PROPERTY(double d READ d WRITE setD)
Q_PROPERTY(string e READ e WRITE setE)
// ...
};Vous pouvez ensuite attribuer une valeur à une propriété de ce type comme suit :
QtObject {
property myValueType v: ({d: 4.4, e: "a string"})
}Les parenthèses supplémentaires sont nécessaires pour distinguer l’objet JavaScript de ce qui pourrait être interprété comme un bloc de code JavaScript.
Vous pouvez également construire des listes de valeurs de cette manière :
QtObject {
property list<myValueType> v: [
{d: 4.4, e: "a string"},
{d: 7.1, e: "another string"}
]
}Cette macro a été introduite dans Qt 6.5.
Voir également QML_VALUE_TYPE et QML_CONSTRUCTIBLE_VALUE.
QML_UNAVAILABLE
Cette macro déclare que le type englobant n'est pas disponible en QML. Elle enregistre un type fictif interne appelé « QQmlTypeNotAvailable » en tant que type « QML_FOREIGN() », en utilisant toute autre macro QML que vous spécifiez.
Normalement, les types exportés par un module doivent être fixes. Cependant, si un type C++ n'est pas disponible, vous devez au moins « réserver » le nom du type QML et afficher un message d'erreur clair à l'utilisateur du type indisponible.
Exemple :
#ifdef NO_GAMES_ALLOWED
struct MinehuntGame
{
Q_GADGET
QML_NAMED_ELEMENT(Game)
QML_UNAVAILABLE
QML_UNCREATABLE("Get back to work, slacker!");
};
#else
class MinehuntGame : public QObject
{
Q_OBJECT
QML_NAMED_ELEMENT(Game)
// ...
};
#endifCela provoquera l’affichage d’un message d’erreur dans tout code QML qui tenterait d’utiliser le type « Game » :
fun.qml: Get back to work, slacker!
Game {
^En utilisant cette technique, vous n’avez besoin que d’une structure ` Q_GADGET ` pour personnaliser le message d’erreur, et non d’un ` QObject` complet. Sans ` QML_UNCREATABLE()`, `QML_UNAVAILABLE` génère tout de même un message d’erreur plus précis que le message habituel « n’est pas un type » pour les types totalement inconnus.
Remarque : le nom de la classe doit être entièrement qualifié, même si vous vous trouvez déjà dans l’espace de noms.
Voir également QML_ELEMENT, QML_NAMED_ELEMENT(), QML_UNCREATABLE() et QML_FOREIGN().
QML_UNCREATABLE(reason)
Déclare que le type englobant ne doit pas pouvoir être créé à partir de QML. Cette restriction s'applique si le type est disponible dans QML, via une macro QML_ELEMENT ou QML_NAMED_ELEMENT(). Le message d'erreur « reason » sera affiché si une tentative de création du type à partir de QML est détectée.
Certains types QML sont implicitement non créables, notamment les types exposés via ` QML_ANONYMOUS ` ou les espaces de noms exposés via ` QML_ELEMENT ` ou ` QML_NAMED_ELEMENT()`.
Si le type est un singleton déclaré avec QML_SINGLETON, l'ajout de QML_UNCREATABLE indique qu'une instance du type sera explicitement définie sur le moteur à l'aide de QQmlEngine::setExternalSingletonInstance.
Depuis Qt 6.0, vous pouvez utiliser « » à la place d'un motif pour utiliser un message standard à la place.
Voir également QML_ELEMENT, QML_NAMED_ELEMENT() et QML_ANONYMOUS.
QML_VALUE_TYPE(name)
Déclare que le type ou l'espace de noms englobant est disponible dans QML, en utilisant name comme nom. Le type doit être un type de valeur et le nom doit être en minuscules.
class MyValueType
{
Q_GADGET
QML_VALUE_TYPE(myValueType)
// ...
};Voir également «Choisir la bonne méthode d'intégration entre C++ et QML » et « QML_NAMED_ELEMENT ».
© 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.