Network Security Internet Technology Development Database Servers Mobile Phone Android Software Apple Software Computer Software News IT Information

In addition to Weibo, there is also WeChat

Please pay attention

WeChat public account

Shulou

Example Analysis of exposing C++ Type attributes to QML

2025-01-16 Update From: SLTechnology News&Howtos shulou NAV: SLTechnology News&Howtos > Development >

Share

Shulou(Shulou.com)06/02 Report--

In this issue, the editor will bring you an example analysis of exposing C++ type attributes to QML. The article is rich in content and analyzed and described from a professional point of view. I hope you can get something after reading this article.

I. data type handling and ownership

Any data transferred from C++ to QML, whether as an attribute value, a method parameter or a return value, or a signal parameter value, must be a type supported by the QML engine.

By default, the engine supports many Qt C++ types and can automatically convert them appropriately when used from QML.

1.1. Expose attributes

You can use the Q_PROPERTY () macro to specify properties for any QObject derived class.

For example, here is a Message class with the author property. As specified by the Q_PROPERTY macro call, this property can be read through the author () method and written by the setAuthor () method:

Note: do not use typedef or using to specify Q_PROPERTY types, as they can confuse moc. This may cause some types to fail.

Misuse:

Using FooEnum = Foo::Enum; class Bar: public QObject {Q_OBJECT Q_PROPERTY (FooEnum enum READ enum WRITE setEnum NOTIFY enumChanged)}

Correct usage:

Class Bar: public QObject {Q_OBJECT Q_PROPERTY (Foo::Enum enum READ enum WRITE setEnum NOTIFY enumChanged)}

Expose attribute instances:

Class Message: public QObject {Q_OBJECT Q_PROPERTY (QString author READ author WRITE setAuthor NOTIFY authorChanged) public: void setAuthor (const QString & a) {if (a! = m_author) {m_author = a; emit authorChanged ();}} QString author () const {return mauthors;} signals: void authorChanged (); private: QString m_author }

If you set an instance of this class to the context property when you load a file named MyItem.qml from C++:

Int main (int argc, char * argv []) {QGuiApplication app (argc, argv); QQuickView view; Message msg; view.engine ()-> rootContext ()-> setContextProperty ("msg", & msg); view.setSource (QUrl::fromLocalFile ("MyItem.qml")); view.show (); return app.exec ();}

You can read the author property from MyItem.qml:

/ / MyItem.qmlimport QtQuick 2.0 Text {width: 100; height: 100 text: msg.author / / call Message::author () to get this value Component.onCompleted: {msg.author = "Jonah" / / call Message::setAuthor ()}}

For maximum interoperability between C++ and QML, any writable property should have an associated NOTIFY signal that is emitted when the property value changes. This allows properties to be used in conjunction with property bindings, a basic feature of QML that enforces relationships between properties by automatically updating properties when the value of any dependency changes. That is, it signals the QML engine to update any bindings that involve attributes.

In the above example, if the author property is writable but does not have an associated NOTIFY signal, the text value is initialized with the initial value returned by Message::author (), but is not updated with any subsequent changes to this property. In addition, any attempt to bind to a property from QML generates a run-time warning from the engine.

It is recommended that you name the NOTIFY signal Changed, where is the name of the attribute. Associated attribute change signal handlers generated by the QML engine will always be in the form of onChanged, regardless of the name of the relevant C++ signal, so it is recommended that signal names follow this convention to avoid any confusion.

1.2. Precautions for the use of notification signals

The developer should ensure that the property change signal is sent only when the property value actually changes. In addition, if an attribute or set of attributes is not used frequently, the same NOTIFY signal is allowed for multiple attributes. This should be done carefully to ensure that performance is not affected.

The presence of NOTIFY signals does incur very little overhead. In some cases, the value of the property is set when the object is constructed and does not change subsequently. In these cases, you can add the CONSTANT attribute instead of the NOTIFY signal to the property declaration.

The CONSTANT property should be used only for properties whose values are set and finally determined in the class constructor.

1.3. Attributes with object type

Object type properties are accessible from QML, provided that the object type is correctly registered with the QML type system.

For example, the Message type may have the body attribute of the MessageBody* type

Class Message: public QObject {Q_OBJECT Q_PROPERTY (MessageBody* body READ body WRITE setBody NOTIFY bodyChanged) public: MessageBody* body () const; void setBody (MessageBody* body);}; class MessageBody: public QObject {Q_OBJECT Q_PROPERTY (QString text READ text WRITE text NOTIFY textChanged) / /.}

Assume that the Message type is already registered in the QML type system

Allow it to be used as an object type in QML code:

Message {/ /...}

If the MessageBody type is also registered with the type system, you can assign MessageBody to the body property of Message:

Message {body: MessageBody {text: "Hello, world!"}} 1.4, attributes with object list type

Properties that contain a list of QObject derived types can also be exposed to QML. However, you should use QQmlListProperty instead of QList as the attribute type. This is because QList is not a type derived from QObject, so the necessary QML attribute characteristics cannot be provided through the Qt meta-object system, such as signal notification when the list is modified.

For example, the following MessageBoard class has a message property of type QQmlListProperty that stores a list of Message instances:

Class MessageBoard: public QObject {Q_OBJECT Q_PROPERTY (QQmlListProperty messages READ messages) public: QQmlListProperty messages () {return QQmlListProperty (this, 0, & MessageBoard::append_message);} private: static void append_message (QQmlListProperty * list, Message * msg) {MessageBoard * msgBoard = qobject_cast (list- > object); if (msg) msgBoard- > m_messages.append (msg);} QList messages;} The template class type of QQmlListProperty (in this case, Message) must be registered with the QML type system. 1.5. Grouping attributes

Any read-only object type property can be accessed from QML code as a grouping property. This can be used to expose a set of related properties that describe a set of properties of a type.

For example, suppose the Message::author attribute is of type MessageAuthor instead of a simple string, with child attributes of name and email:

Class MessageAuthor: public QObject {Q_PROPERTY (QString name READ name WRITE setName) Q_PROPERTY (QString email READ email WRITE setEmail) public:...}; class Message: public QObject {Q_OBJECT Q_PROPERTY (MessageAuthor* author READ author) public: Message (QObject * parent): QObject (parent), m_author (new MessageAuthor (this)) {} MessageAuthor* author () const {return mauthors;} private: MessageAuthor* m_author }

You can write author properties using the grouping attribute syntax in QML:

Message {author.name: "Alexandra" author.email: "alexandra@mail.com"}

The grouping property is read-only and is initialized by the parent object to a valid value at construction time.

The child properties of the grouping property can be modified from the QML, but the grouping property object itself will never change.

2. Exposure method

Any method of a QObject derived type can be accessed from QML code, as long as it satisfies one of the following:

Public methods marked with the Q_INVOKABLE () macro

As a method of public slot

For example, the following MessageBoard class has a postMessage () method marked with a Q_INVOKABLE macro, and a refresh () method for a common slot:

Class MessageBoard: public QObject {Q_OBJECTpublic: Q_INVOKABLE bool postMessage (const QString & msg) {qDebug () console.log ("New message received:", subject)}

Like property values and method parameters, signal parameters must have types supported by the QML engine. (using an unregistered type will not cause an error, but the handler will not be able to access the parameter value. )

Note that the QML engine cannot distinguish between signals with the same name but different parameters, and the class may have multiple signals with the same name, but only the last signal can be accessed as a QML signal.

The above is the analysis of the example of exposing C++ type attributes to QML shared by Xiaobian. If you happen to have similar doubts, please refer to the above analysis to understand. If you want to know more about it, you are welcome to follow the industry information channel.

Welcome to subscribe "Shulou Technology Information " to get latest news, interesting things and hot topics in the IT industry, and controls the hottest and latest Internet news, technology news and IT industry trends.

Views: 0

*The comments in the above article only represent the author's personal views and do not represent the views and positions of this website. If you have more insights, please feel free to contribute and share.

Share To

Development

Wechat

© 2024 shulou.com SLNews company. All rights reserved.

12
Report