<qqmlintegration.h> - Registering C++ types to QML

Header: #include <QtQmlIntegration/qqmlintegration.h>

Makros

Detaillierte Beschreibung

Dieser Header stellt Makros zur Verfügung, die verwendet werden können, um C++-Typen in QML zu registrieren.

Siehe auch qt_generate_foreign_qml_types, Übersicht - QML und C++ Integration, und qmltyperegistrar.

Makro-Dokumentation

QML_ADDED_IN_VERSION(MAJOR, MINOR)

Deklariert, dass der umschließende Typ oder Namespace in der angegebenen MAJOR.MINOR Version hinzugefügt wurde. Es wird angenommen, dass die Version mit allen Revisionen übereinstimmt, die durch Q_REVISION()-Makros für Methoden, Slots oder Signale und durch REVISION()-Attribute für mit Q_PROPERTY() deklarierte Eigenschaften angegeben wurden.

QML_ADDED_IN_VERSION() wird nur wirksam, wenn der Typ oder Namespace in QML verfügbar ist, indem ein QML_ELEMENT, QML_NAMED_ELEMENT(), QML_ANONYMOUS oder QML_INTERFACE Makro vorhanden ist.

Wenn das QML-Modul, zu dem der Typ gehört, mit einer niedrigeren Version als der auf diese Weise ermittelten importiert wird, ist der QML-Typ unsichtbar.

Siehe auch QML_ELEMENT und QML_NAMED_ELEMENT.

QML_ANONYMOUS

Deklariert den umschließenden Typ als verfügbar, aber anonym in QML. Der Typ kann nicht erstellt oder zur Deklaration von Eigenschaften in QML verwendet werden, wird aber bei der Übergabe aus C++ erkannt. In QML können Sie Eigenschaften dieses Typs verwenden, wenn sie in C++ deklariert sind.

Siehe auch QML_ELEMENT, QML_NAMED_ELEMENT(), QML_UNCREATABLE(), und QML_INTERFACE.

QML_ATTACHED(ATTACHED_TYPE)

Deklariert, dass der umschließende Typ ATTACHED_TYPE als angehängte Eigenschaft an andere Typen anhängt. Dies wird wirksam, wenn der Typ mit einem QML_ELEMENT oder QML_NAMED_ELEMENT() Makro in QML exponiert ist.

Hinweis: Der Klassenname muss voll qualifiziert sein, auch wenn Sie sich bereits innerhalb des Namespaces befinden.

Siehe auch QML_ELEMENT, QML_NAMED_ELEMENT(), qmlAttachedPropertiesObject(), und Bereitstellen von angehängten Eigenschaften.

[since 6.5] QML_CONSTRUCTIBLE_VALUE

Markiert den umgebenden Werttyp als konstruierbar. Das heißt, alle Q_INVOKABLE Konstruktoren des Typs, die genau ein Argument annehmen, können verwendet werden, wenn einer Eigenschaft dieses Typs ein JavaScript-Wert zugewiesen wird.

Sie können einen konstruierbaren Wertetyp wie folgt deklarieren:

class MyValueType
{
    Q_GADGET
    QML_VALUE_TYPE(myValueType)
    QML_CONSTRUCTIBLE_VALUE
public:
    Q_INVOKABLE MyValueType(double d);

    // ...
};

Mit dem obigen Typ erzeugt der folgende QML-Code einen MyValueType Wert unter Verwendung des angegebenen Konstruktors und weist ihn der Eigenschaft zu.

QtObject {
    property myValueType v: 5.4
}

Sie können auch Listen von Werten auf diese Weise konstruieren:

QtObject {
    property list<myValueType> v: [5.4, 4.5, 3.3]
}

Wenn Sie Wertetypen adressierbar machen, können Sie einen solchen Typ in einer Type Assertion verwenden, um ihn explizit zu konstruieren:

pragma ValueTypeBehavior: Addressable

QtObject {
    function process(d: real) {
        let v = d as myValueType;
        // v is a myValueType now, not a number
    }
}

Dieses Makro wurde in Qt 6.5 eingeführt.

Siehe auch QML_VALUE_TYPE.

QML_ELEMENT

Deklariert den umschließenden Typ oder Namespace als in QML verfügbar, wobei sein Klassen- oder Namespace-Name als QML-Elementname verwendet wird.

Dadurch wird beispielsweise die C++-Klasse Slider als QML-Typ mit dem Namen Slider verfügbar. Alle ihre Eigenschaften, aufrufbaren Methoden und Enums sind verfügbar.

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);

    // ...
}

Sie können das Build-System verwenden, um den Typ im Typ-Namensraum com.mycompany.qmlcomponents mit der Hauptversion 1 zu registrieren. Für qmake geben Sie folgendes in Ihrer Projektdatei an:

CONFIG += qmltypes
QML_IMPORT_NAME = com.mycompany.qmlcomponents
QML_IMPORT_MAJOR_VERSION = 1

Mit CMake übergeben Sie den URI und die Version an qt_add_qml_module

qt6_add_qml_module(myapp
  URI com.mycompany.qmlcomponents
  VERSION 1.0
)

Sobald der Typ registriert ist, kann er in QML verwendet werden, indem man den gleichen Typ-Namensraum und die gleiche Versionsnummer importiert:

import com.mycompany.qmlcomponents 1.0

Slider {
    value: 12
    Component.onCompleted: slide(Slider.Icy)

    // ...
}

Sie können auf diese Weise auch Namespaces, die mit Q_NAMESPACE gekennzeichnet sind, verfügbar machen, um alle Enums, die mit Q_ENUM_NS gekennzeichnet sind, offenzulegen:

namespace MyNamespace {
  Q_NAMESPACE
  QML_ELEMENT

  enum MyEnum {
      Key1,
      Key2,
  };
  Q_ENUM_NS(MyEnum)
}

In QML können Sie dann die Enums verwenden:

Component.onCompleted: console.log(MyNamespace.Key2)

HINWEIS: Wenn Klassen den gleichen Namen haben, aber in verschiedenen Namespaces liegen, führt die Verwendung von QML_ELEMENT für beide zu einem Konflikt. Stellen Sie sicher, dass Sie stattdessen QML_NAMED_ELEMENT() für eine der beiden Klassen verwenden.

Hinweis: Der Klassenname muss voll qualifiziert sein, auch wenn Sie sich bereits innerhalb des Namespaces befinden.

Siehe auch Auswahl der korrekten Integrationsmethode zwischen C++ und QML, QML_NAMED_ELEMENT(), Q_REVISION() und QML_ADDED_IN_VERSION().

QML_EXTENDED(EXTENDED_TYPE)

Deklariert, dass der umschließende Typ EXTENDED_TYPE als Erweiterung verwendet, um weitere Eigenschaften, Methoden und Aufzählungen in QML bereitzustellen. Dies wird wirksam, wenn der Typ in QML mit einem QML_ELEMENT oder QML_NAMED_ELEMENT() Makro dargestellt wird.

Warnung: Die Mitglieder von EXTENDED_TYPE werden implizit als FINAL behandelt.

Hinweis: Der Klassenname muss voll qualifiziert sein, auch wenn Sie sich bereits innerhalb des Namespaces befinden.

Siehe auch QML_ELEMENT, QML_NAMED_ELEMENT(), QML_EXTENDED_NAMESPACE(), und Registrierung von Erweiterungsobjekten.

QML_EXTENDED_NAMESPACE(EXTENSION_NAMESPACE)

Deklariert, dass der umschließende Typ EXTENSION_NAMESPACE als Erweiterung verwendet, um weitere Aufzählungen in QML bereitzustellen. Dies wird wirksam, wenn der Typ in QML mit einem QML_ELEMENT oder QML_NAMED_ELEMENT() Makro dargestellt wird. Damit dies funktioniert, müssen die Aufzählungen dem Metaobjektsystem ausgesetzt sein.

Nehmen wir zum Beispiel den folgenden C++-Code

namespace MyNamespace {
    Q_NAMESPACE
    enum MyEnum { MyEnumerator = 10 };
    Q_ENUM_NS(MyEnum)
}

class QmlType : public QObject
{
    Q_OBJECT
    QML_ELEMENT
    QML_EXTENDED_NAMESPACE(MyNamespace)
}

können wir auf die Aufzählung in QML zugreifen:

QmlType {
    property int i: QmlType.MyEnumerator // i will be 10
}

Hinweis: EXTENSION_NAMESPACE kann auch ein QObject oder QGadget sein; in diesem Fall - und im Gegensatz zu QML_EXTENDED, das auch Methoden und Eigenschaften offenlegt - werden nur seine Aufzählungen offengelegt.

Hinweis: EXTENSION_NAMESPACE muss ein Metaobjekt haben, d.h. es muss entweder ein Namespace sein, der das Makro Q_NAMESPACE enthält oder ein QObject/QGadget.

Hinweis: Der Klassenname muss voll qualifiziert sein, auch wenn Sie sich bereits innerhalb des Namespaces befinden.

Siehe auch QML_NAMESPACE_EXTENDED(), QML_ELEMENT, QML_NAMED_ELEMENT(), QML_EXTENDED(), Registrierung von Erweiterungsobjekten, Q_ENUM, und Q_ENUM_NS.

QML_EXTRA_VERSION(MAJOR, MINOR)

Geben Sie an, dass der Typ auch in der Version MAJOR verfügbar sein soll.MINOR. Dies kann hilfreich sein, wenn ein Typ in mehreren Hauptversionen verfügbar sein soll.

Typen werden automatisch registriert für:

  • Die Hauptversion, in der sie eingeführt wurden, siehe QML_ADDED_IN_VERSION.
  • Alle Hauptversionen, in denen ihre Mitglieder eingeführt wurden.
  • Die aktuelle Hauptversion ihres Moduls, es sei denn, sie waren vorher QML_REMOVED_IN_VERSION.

Insbesondere werden sie nicht automatisch in allen PAST_MAJOR_VERSIONS zwischen den oben genannten registriert. Sie können QML_EXTRA_VERSION verwenden, um Ihre Typen manuell in weiteren Hauptversionen zu registrieren.

Hinweis: Die Beibehaltung mehrerer PAST_MAJOR_VERSIONS ist rechenintensiv.

Siehe auch QML_ELEMENT und QML_ADDED_IN_VERSION.

QML_FOREIGN(FOREIGN_TYPE)

Deklariert, dass alle 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() oder QML_NAMESPACE_EXTENDED() Makros im umschließenden C++-Typ nicht für den umschließenden Typ, sondern für FOREIGN_TYPE gelten. Der umschließende Typ muss weiterhin mit einem Q_GADGET oder Q_OBJECT Makro im Meta-Objektsystem registriert werden.

Dies ist nützlich für die Registrierung von Typen, die nicht geändert werden können, um die Makros hinzuzufügen, zum Beispiel weil sie zu Bibliotheken von Drittanbietern gehören. Um einen Namespace zu registrieren, siehe QML_FOREIGN_NAMESPACE().

Hinweis: Möglicherweise möchten Sie QML_NAMED_ELEMENT() anstelle von QML_ELEMENT verwenden. Mit QML_ELEMENT wird das Element nach der Struktur benannt, in der es enthalten ist, nicht nach dem fremden Typ. Das Kapitel Integration fremder Objekte in Writing advanced QML Extensions with C++ demonstriert dies.

Hinweis: QML_ATTACHED() kann derzeit nicht auf diese Weise umgelenkt werden. Sie muss in demselben Typ spezifiziert werden, der qmlAttachedProperties() implementiert.

Hinweis: Der Klassenname muss voll qualifiziert sein, auch wenn Sie sich bereits innerhalb des Namespaces befinden.

Siehe auch QML_ELEMENT, QML_NAMED_ELEMENT(), und QML_FOREIGN_NAMESPACE().

QML_FOREIGN_NAMESPACE(FOREIGN_NAMESPACE)

Deklariert, dass alle 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() oder QML_REMOVED_IN_MINOR_VERSION() Makros im umschließenden C++-Namensraum nicht für den umschließenden Typ, sondern für FOREIGN_NAMESPACE gelten. Der umschließende Namensraum muss weiterhin mit einem Q_NAMESPACE -Makro im Meta-Objektsystem registriert werden.

Dies ist nützlich für die Registrierung von Namespaces, die nicht geändert werden können, um die Makros hinzuzufügen, z. B. weil sie zu Bibliotheken von Drittanbietern gehören.

Siehe auch QML_ELEMENT, QML_NAMED_ELEMENT(), und QML_FOREIGN().

QML_IMPLEMENTS_INTERFACES(interfaces)

Dieses Makro teilt Qt mit, welche QML interfaces die Klasse implementiert. Dieses Makro sollte nur für Schnittstellen mit Klassen verwendet werden, die QML_INTERFACE verwenden, andernfalls verwenden Sie Q_INTERFACES. Es wird benötigt, damit die deklarative Registrierung über QML_ELEMENT richtig funktioniert.

Siehe auch QML_INTERFACE und Q_INTERFACES.

QML_INTERFACE

Dieses Makro registriert den umschließenden C++-Typ im QML-System als Schnittstelle.

Typen, die als Schnittstelle in QML registriert sind, sollten sich selbst auch als Schnittstelle im Meta-Objektsystem deklarieren. Ein Beispiel:

struct FooInterface
{
    QML_INTERFACE
public:
    virtual ~FooInterface();
    virtual void doSomething() = 0;
};

Q_DECLARE_INTERFACE(FooInterface, "org.foo.FooInterface")

Wenn sie auf diese Weise bei QML registriert sind, können sie als Eigenschaftstypen verwendet werden:

Q_PROPERTY(FooInterface *foo READ foo WRITE setFoo)

Wenn Sie dieser Eigenschaft eine Unterklasse von QObject zuweisen, führt die QML-Engine den Schnittstellen-Cast nach FooInterface* automatisch durch.

Schnittstellentypen sind in QML implizit anonym und nicht anlegbar.

HINWEIS: Wenn Sie von Typen mit QML_INTERFACE erben, verwenden Sie QML_IMPLEMENTS_INTERFACES anstelle von Q_INTERFACES.

Siehe auch QML_IMPLEMENTS_INTERFACES(), QML_ELEMENT, QML_NAMED_ELEMENT(), QML_UNCREATABLE(), und QML_ANONYMOUS.

QML_NAMED_ELEMENT(name)

Deklariert den umschließenden Typ oder Namespace als in QML verfügbar, wobei name als Elementname verwendet wird. Andernfalls verhält es sich genauso wie QML_ELEMENT.

class SqlEventDatabase : public QObject
{
    Q_OBJECT
    QML_NAMED_ELEMENT(EventDatabase)

    // ...
};

Siehe auch Auswahl der korrekten Integrationsmethode zwischen C++ und QML und QML_ELEMENT.

QML_REMOVED_IN_VERSION(MAJOR, MINOR)

Deklariert, dass der umschließende Typ oder Namespace in der angegebenen MAJOR.MINOR Version entfernt wurde. Dies ist vor allem dann nützlich, wenn die Implementierung eines QML-Typs ersetzt werden soll. Wenn ein entsprechendes QML_ADDED_IN_VERSION() auf einem anderen Typ oder Namespace des gleichen QML-Namens vorhanden ist, wird der entfernte Typ verwendet, wenn Versionen des Moduls kleiner als MAJOR.MINOR importiert werden, und der hinzugefügte Typ wird verwendet, wenn Versionen des Moduls größer oder gleich MAJOR.MINOR importiert werden.

QML_REMOVED_IN_VERSION() wird nur wirksam, wenn der Typ oder Namespace in QML verfügbar ist, indem ein QML_ELEMENT, QML_NAMED_ELEMENT(), QML_ANONYMOUS oder QML_INTERFACE Makro vorhanden ist.

Siehe auch QML_ELEMENT und QML_NAMED_ELEMENT.

QML_SEQUENTIAL_CONTAINER(VALUE_TYPE)

Dieses Makro deklariert den umschließenden oder referenzierten Typ als einen sequentiellen Container, der eine Folge von VALUE_TYPE Elementen verwaltet. VALUE_TYPE kann ein tatsächlicher Werttyp oder ein Zeiger auf einen Objekttyp sein. Es ist selten möglich, dieses Makro der eigentlichen Containerdeklaration hinzuzufügen, da Container normalerweise Vorlagen sind. Sie sollten QML_FOREIGN verwenden, um die Typregistrierung an eine Vorlageninstanziierung anzuhängen. Mit dieser Technik können Sie z. B. sequenzielle Container wie folgt deklarieren:

class IntDequeRegistration
{
  Q_GADGET
  QML_FOREIGN(std::deque<int>)
  QML_ANONYMOUS
  QML_SEQUENTIAL_CONTAINER(int)
};

Danach können Sie den Container wie ein JavaScript-Array in QML verwenden.

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([...])
  }
}

Hinweis: Für QML-Wertetypen wird QList automatisch als sequentieller Container registriert. Für QML-Objekttypen ist QQmlListProperty. Sie müssen diese Registrierungen nicht hinzufügen.

Hinweis: Sie können dem Container derzeit keinen eigenen Namen geben. Jedes Argument, das an QML_NAMED_ELEMENT übergeben wird, wird ignoriert. Die automatisch registrierten sequentiellen Container sind unter den bekannten list<...> Namen verfügbar, zum Beispiel list<QtObject> oder list<font>.

Hinweis: Der Klassenname muss voll qualifiziert sein, auch wenn man sich bereits im Namespace befindet.

Siehe auch QML_ANONYMOUS und QML_FOREIGN().

QML_SINGLETON

Deklariert den umschließenden Typ zu einem Singleton in QML. Dies wird nur wirksam, wenn der Typ ein Q_OBJECT ist und in QML verfügbar ist (durch ein QML_ELEMENT oder QML_NAMED_ELEMENT() Makro). Standardmäßig versucht QQmlEngine beim ersten Zugriff auf den Typ eine Singleton-Instanz entweder mit dem Standardkonstruktor des Typs oder mit einer statischen Fabrikfunktion der Signatur T *create(QQmlEngine *, QJSEngine *) zu erzeugen. Wenn beide existieren und zugänglich sind, wird der Standard-Konstruktor bevorzugt. Wenn es keinen Standardkonstruktor und keine Fabrikfunktion gibt, ist das Singleton unzugänglich. Die QML-Engine übernimmt im Allgemeinen den Besitz des Singletons und wird es löschen, wenn die Engine selbst zerstört wird. Sie können dies verhindern, indem Sie QJSEngine::setObjectOwnership() für das Singleton aufrufen.

Um eine standardmäßig konstruierbare Klasse als Singleton zu deklarieren, müssen Sie nur QML_SINGLETON hinzufügen:

class MySingleton : public QObject
{
    Q_OBJECT
    QML_ELEMENT
    QML_SINGLETON
    // Q_PROPERTY( ... )
public:
    // members, Q_INVOKABLE functions, etc.
};

Wenn die Singleton-Klasse nicht standardmäßig konstruierbar ist, Sie sie aber ändern können, können Sie ihr eine Factory-Funktion hinzufügen, um sie zugänglich zu machen:

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
};

Wenn Sie die Klasse nicht modifizieren können und sie weder einen Standardkonstruktor noch eine geeignete Fabrikfunktion hat, können Sie einen QML_FOREIGN Wrapper bereitstellen, um die Fabrikfunktion zu definieren:

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;
    }
};

Wenn Sie schließlich ein bestimmtes Singleton-Objekt bereitstellen möchten, dessen Erstellung Sie nicht kontrollieren können, können Sie dieses von einer Fabrikfunktion zurückgeben. Dies ist ein Ersatz für die Funktion qmlRegisterSingletonInstance. Wenn Sie die Funktion

qmlRegisterSingletonInstance("MyModule", 1, 0, "MySingleton", myObject);

aufrufen, wobei myObject vom Typ MySingleton * ist, können Sie stattdessen Folgendes tun:

struct SingletonForeign
{
    Q_GADGET
    QML_FOREIGN(MySingleton)
    QML_SINGLETON
    QML_NAMED_ELEMENT(MySingleton)
public:

    // Initialize this using myObject where you would previously
    // call qmlRegisterSingletonInstance().
    inline static MySingleton *s_singletonInstance = nullptr;

    static MySingleton *create(QQmlEngine *, QJSEngine *engine)
    {
        // The instance has to exist before it is used. We cannot replace it.
        Q_ASSERT(s_singletonInstance);

        // The engine has to have the same thread affinity as the singleton.
        Q_ASSERT(engine->thread() == s_singletonInstance->thread());

        // There can only be one engine accessing the singleton.
        if (s_engine)
            Q_ASSERT(engine == s_engine);
        else
            s_engine = engine;

        // Explicitly specify C++ ownership so that the engine doesn't delete
        // the instance.
        QJSEngine::setObjectOwnership(s_singletonInstance,
                                      QJSEngine::CppOwnership);
        return s_singletonInstance;
    }

private:
    inline static QJSEngine *s_engine = nullptr;
};

Auf diese Weise wird die bereits existierende Klasse MySingleton zu einem QML-Singleton mit dem Namen MySingleton deklariert. Sie können jederzeit eine Instanz für sie angeben, bevor sie verwendet wird, indem Sie das Mitglied s_singletonInstance setzen. Nichts von alledem erfordert eine Änderung von MySingleton selbst.

Hinweis: Dieses Muster funktioniert nicht, wenn auf das Singleton entweder von mehreren QML-Engines zugegriffen wird oder wenn die QML-Engine, die darauf zugreift, eine andere Thread-Affinität hat als das Singleton-Objekt selbst. Wie oben gezeigt, können Sie die Parameter der Methode create() auf Identität und Thread-Affinität der Engine überprüfen, um dies zu bestätigen.

Siehe auch QML_ELEMENT, QML_NAMED_ELEMENT(), qmlRegisterSingletonInstance(), QQmlEngine::singletonInstance(), und Singletons in QML.

[since 6.5] QML_STRUCTURED_VALUE

Markiert den umgebenden Wertetyp als strukturiert. Strukturierte Wertetypen können und werden vorzugsweise property-by-property aus einem JavaScript-Objekt konstruiert. Ein strukturierter Wertetyp ist jedoch immer auch QML_CONSTRUCTIBLE_VALUE. Das bedeutet, dass Sie immer noch Q_INVOKABLE Konstruktoren zur Verfügung stellen können, um die Konstruktion aus primitiven Typen zu handhaben.

Sie können einen strukturierten Wertetyp wie folgt deklarieren:

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)

    // ...
};

Dann können Sie eine Eigenschaft dieses Typs wie folgt ausfüllen:

QtObject {
    property myValueType v: ({d: 4.4, e: "a string"})
}

Die zusätzlichen Klammern sind notwendig, um das JavaScript-Objekt von dem zu unterscheiden, was als JavaScript-Codeblock interpretiert werden könnte.

Sie können auch Listen von Werten auf diese Weise konstruieren:

QtObject {
    property list<myValueType> v: [
        {d: 4.4, e: "a string"},
        {d: 7.1, e: "another string"}
    ]
}

Wenn Sie Wertetypen adressierbar machen, können Sie einen solchen Typ in einer Type Assertion verwenden, um ihn explizit zu konstruieren:

pragma ValueTypeBehavior: Addressable

QtObject {
    function process(d: real) {
        let v = {d: d, e: objectName} as myValueType;
        // v is a myValueType now
    }
}

Dieses Makro wurde in Qt 6.5 eingeführt.

Siehe auch QML_VALUE_TYPE und QML_CONSTRUCTIBLE_VALUE.

QML_UNAVAILABLE

Dieses Makro deklariert den umschließenden Typ als in QML nicht verfügbar. Es registriert einen internen Dummy-Typ mit der Bezeichnung QQmlTypeNotAvailable als QML_FOREIGN()-Typ und verwendet alle weiteren von Ihnen angegebenen QML-Makros.

Normalerweise sollten die von einem Modul exportierten Typen fest sein. Wenn jedoch ein C++-Typ nicht verfügbar ist, sollten Sie zumindest den QML-Typnamen "reservieren" und dem Benutzer des nicht verfügbaren Typs eine sinnvolle Fehlermeldung geben.

Beispiel:

#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)
    // ...
};
#endif

Dies führt dazu, dass jede QML, die versucht, den Typ "Game" zu verwenden, eine Fehlermeldung erzeugt:

fun.qml: Get back to work, slacker!
   Game {
   ^

Mit dieser Technik benötigen Sie nur eine Q_GADGET struct, um die Fehlermeldung anzupassen, und keine vollwertige QObject. Ohne QML_UNCREATABLE() führt QML_UNAVAILABLE immer noch zu einer spezifischeren Fehlermeldung als die übliche "is not a type" für völlig unbekannte Typen.

Hinweis: Der Klassenname muss voll qualifiziert sein, auch wenn Sie sich bereits innerhalb des Namespaces befinden.

Siehe auch QML_ELEMENT, QML_NAMED_ELEMENT(), QML_UNCREATABLE(), und QML_FOREIGN().

QML_UNCREATABLE(reason)

Deklariert, dass der umschließende Typ nicht aus QML erzeugt werden kann. Dies tritt in Kraft, wenn der Typ in QML verfügbar ist, indem er ein QML_ELEMENT oder QML_NAMED_ELEMENT() Makro hat. Das reason wird als Fehlermeldung ausgegeben, wenn ein Versuch, den Typ aus QML zu erstellen, erkannt wird.

Einige QML-Typen sind implizit nicht anlegbar, insbesondere Typen, die mit QML_ANONYMOUS oder Namespaces, die mit QML_ELEMENT oder QML_NAMED_ELEMENT() angezeigt werden.

Seit Qt 6.0 können Sie "" anstelle eines Grundes verwenden, um stattdessen eine Standardmeldung zu verwenden.

Siehe auch QML_ELEMENT, QML_NAMED_ELEMENT(), und QML_ANONYMOUS.

QML_VALUE_TYPE(name)

Deklariert den umschließenden Typ oder Namespace, der in QML verfügbar sein soll, unter Verwendung von name als Name. Der Typ muss ein Wertetyp sein und der Name muss klein geschrieben werden.

class MyValueType
{
    Q_GADGET
    QML_VALUE_TYPE(myValueType)

    // ...
};

Siehe auch Auswahl der korrekten Integrationsmethode zwischen C++ und QML und QML_NAMED_ELEMENT.

© 2025 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.