Discussion and summary of QML and QT C + + interaction mechanism

Source: Internet
Author: User
Tags emit signal handler

Translated from https://www.cnblogs.com/aoldman/p/4103510.html

Introduced

QML and C + + objects can interact through, signals,slots, and property modifications. For a C + + object, any data can be exposed to QML via QT's Meta-object system (the total method, described later), and any QML object data is directly accessed by the Meta-object system on the C + + side.
QML and Qt C + + interactions are used in many areas of the actual project. Here summarizes a number of methods for your reference, welcome everyone to guide and shoot bricks.

There are three ways to do this:
1. Expose the objects or types in qt C + + to the QML end for use on the QML side. (The official phrase is "embedding" rather than "exposing" and more civilized.) -B)
2. The signal Handler in QML (equivalent to QT C + + sends a signal to the QML end, QML signal for processing).
3. Create the Qml object on the QT C + + side, since the objects are all there. Well, what do you want to do with it? (not used, it seems not very practical, but introduction, useful students message ha).

Okay, let's get started.

Knowledge Preparation

Don't worry, let's take a look at some things, if you know, you can skip this section.
The QML API has three main members--qdeclarativeengine,qdeclarativecomponent and Qdeclarativecontext.

The Qdeclarativeengine provides a QML operating environment.
The qdeclarativecomponent encapsulates QML Documents.
Qdeclarativecontext allows programs to display data using the QML component.

The QML contains a very useful api--qdeclarativeview. With it, the application can easily embed the QML component into the Qgraphicsview. Qdeclarativeview is primarily used for rapid prototyping during application development.

Exposing QT C + + objects or types to QML create data types that need to be exposed to QML
#ifndef Myclass_h
#define Myclass_h
#include <QObject>
#include <QString>
Class Myclass:public Qobject
{
Q_object
Q_property (QString myString READ myString WRITE setmystring NOTIFY mystringchanged)
Public
Explicit MyClass (Qobject *parent = 0);
Q_invokable QString getmystring ();
Signals:
void Mystringchanged ();
Public Slots:
void Setmystring (QString astring);
QString myString ();
Private
QString m_string;
};
#endif//Myclass_h

If you want a method in the data element to be called directly by QML there are 2 methods:
1. Add the Q_invokable macro before the function declaration.
2. Declare as public slots.

QML can directly access the properties of the modified data element, as declared by Qproperty.
For specific implementations, refer to the sample code.

Exposing an existing QT C + + object to QML
Main.cpp
MyClass MYOBJ;
Qdeclarativeengine *engine=viewer.engine ();
Qdeclarativecontext *context=engine->rootcontext ();
Context->setcontextproperty ("Myobjectexposebycxproperty", &myobj);

The Myobjectexposebycxproperty object can be used directly in QML.

Mainpage.qml
...
button{
...
Id:btn1
...

The Qproperty property called MyString MyClass here is not a method, so there is no parentheses.
onclicked:label.text=myobjectexposebycxproperty.mystring;
}
...
Register QT C + + class type to QML

Another way is to register the type
Main.cpp
Qmlregistertype<myclass> ("Registermytype", 1, 0, "Myclasstype");

This is used in QML
Mainpage.qml
...
Import Registermytype 1.0
button{
Id:btn2
...
Text:qstr ("inovkable")
The Invokable method, which is called here, is not a property, so there are parentheses.
Onclicked:label.text=myclassexposebyregtype.getmystring ();
}
Creating the object, since QML is interpreted, so it doesn't matter what's behind it.
Myclasstype
{
Id:myclassexposebyregtype
}

Steps:
1. Import imports.
2. Create the object.
3. Use the ID directly.
The signal Handler in QML

Or using the above example, in QML, click the button control, change the string of the object, this time in QT C + + send a signal signal to the QML end, the QML side received the use of signal handler response, change the value of Label2. The specific code is as follows.
Modifies the value of string in QML.
Mainpage.qml
button{
Id:btn3
Text:qstr ("Emit stringchanged Signal")

}

Qt C + + trigger signal
Myclass.cpp
void Myclass::setmystring (QString astring)
{
if (astring==m_string)
{
Return
}
m_string=astring;
Emit mystringchanged ();
}

Connection Signal Handler response
Mainpage.qml
Connections
{
Target:myobjectexposebycxproperty

}

In the form of a parameter:
Basic ideas and concrete steps

The basic idea is to expose the objects in your QT C + + to the QML side, then use Signals-slots to connect and deliver the message. The steps are as follows
1 Create your own object, if your object is to be displayed on the QML side, you can inherit the Qdeclarativeitem, if it is just a control class and does not need to be displayed on the qml side, just inherit qobject. For data binding here, refer to using QML Bindings in C + + applications

#include <QObject>
Class Netconnectcontroller:public Qobject
{
Q_object
Q_property (int status READ status WRITE setStatus NOTIFY statuschanged)
Public
Explicit Netconnectcontroller (Qobject *parent = 0);

void Ready ()
{
Emit statuschanged (m_status);
}
Signals:
void statuschanged (int astatus);
Private
int status () const;
void setStatus (int astatus);
Private:
Indicates a different state of the network
int m_status;
};


2 exposing your object to QML

.....
Netconnectcontroller Netcontroller
Qdeclarativeengine * engine = Viewer.engine ();
(Engine->rootcontext ())->setcontextproperty ("Netcontroller", &netcontroller);
.....

3 Connecting Signal-slot in QML

......

Connections
{
Target:netcontroller
Onstatuschanged:changestatus (astatus)//call JS Function
}
......

Note: The above onstatuschanged naming format "on" + "signal name in Qt C + +". The parameters of the QT C-side can be used directly on the QML side. For example, "Astatus" above.

Functions that call QML directly in Qt C + +

The same QML function can also be called by the QT C + + side.
All QML functions are exposed to the QT C + + END through the Meta-object system and can be called directly on the QT C + + side using the Qmetaobject::invokemethod () method. Here is an example of this.
Myitem.qml
Import QtQuick 1.0
Item {
function Myqmlfunction (msg) {
Console.log ("Got message:", msg)
Return "Some return value"
}
}
Main.cpp
Qdeclarativeengine engine;
Qdeclarativecomponent component (&engine, "myitem.qml");
Qobject *object = Component.create ();
Qvariant Returnedvalue;
Qvariant msg = "Hello from C + +";
Qmetaobject::invokemethod (Object, "Myqmlfunction",
Q_return_arg (Qvariant, Returnedvalue),
Q_arg (Qvariant, msg));
Qdebug () << "QML function returned:" << returnedvalue.tostring ();
Delete object;


More routines can be found in the installation directory of the SDK: \qtsdk\examples\4.7\declarative\tutorials\extending.

Discussion and summary of QML and QT C + + interaction mechanism (turn)

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.