Discussion and summary of the interaction between QML and Qt C ++, qmlqt

Source: Internet
Author: User
Tags signal handler

Discussion and summary of the interaction between QML and Qt C ++, qmlqt
Introduction

QML and C ++ objects can interact with each other through, signals, slots, and attribute modification. For a C ++ Object, any data can be exposed to QML through Qt's Meta-Object System (HE Zong method, which will be described later). At the same time, any QML object data is directly accessed through the Meta-object system on the C ++ side.
In actual projects, QML and Qt C ++ are used in many places. I have summarized a number of methods for your reference. You are welcome to provide guidance and suggestions.

There are three methods:
1. Expose the objects or types in Qt C ++ to the qml end for use by the QML end. (The official saying is "embedding" rather than "exposing", which is more civilized. --B)
2. Signal Handler in QML (equivalent to sending signals to QML and QML Signal Handler ).
3. Create a QML object on the Qt C ++ client. Now that all objects have a QML object. That's how you want it. (I have never used it, and it does not seem practical, but I will introduce it and leave a message for those who have used it ).

Okay. Let's get started ~

Knowledge preparation

Don't worry. Let's take a look. If you know something, you can skip this section.
QML APIs include QDeclarativeEngine, QDeclarativeComponent, and QDeclarativeContext.

QDeclarativeEngine provides the QML runtime environment.
QDeclarativeComponent encapsulates QML Documents.
QDeclarativeContext allows the program to use the QML component to display data.

QML contains a very useful API-QDeclarativeView. Through it, the application can easily embed the QML component into the QGraphicsView. QDeclarativeView is mainly used for rapid prototyping during application development.

Expose the objects or types of Qt C ++ to QML and create the data types 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 to call the methods in data elements directly by QML, there are two methods:
1. Add the Q_INVOKABLE macro before the function declaration.
2. Declare it as public slots.

QML can directly access and modify the attribute of a data element, which is stated by QPROPERTY.
For specific implementation, see the sample code.

Expose existing Qt C ++ objects to QML
//main.cpp
MyClass myObj;
QDeclarativeEngine *engine=viewer.engine();
QDeclarativeContext *context=engine->rootContext();
context->setContextProperty("myObjectExposeByCXProperty", &myObj);

You can directly use the myObjectExposeByCxProperty object in qml.

// Mainpage. qml
...
Button {
...
Id: btn1
...
Text: qsTr ("PROPERTY ")
// The Property of QPROPERTY whose myString is MyClass is called here is not a method, so no parentheses exist.
OnClicked: label. text = myObjectExposeByCXProperty. myString;
}
...
 
Register the Qt C ++ class type to QML 

Another method is the registration type.
//main.cpp
qmlRegisterType<MyClass>("RegisterMyType", 1, 0, "MyClassType");

QML
// Mainpage. qml
...
Import RegisterMyType 1.0
Button {
Id: btn2
...
Text: qsTr ("INOVKABLE ")
// The INVOKABLE method called here is not an attribute, so there are brackets.
OnClicked: label. text = myclassExposeByRegType. getMyString ();
}
// Create an object. Since QML is interpreted and executed, it does not matter if it is placed later.
MyClassType
{
Id: myclassExposeByRegType
}

Steps:
1. import.
2. Create an object.
3. Use id directly.
Signal Handler in QML

In the above example, click the button control in qml to change the object string. At this time, a signal is sent to the qml end in Qt C ++, the qml side receives a response using signal handler and changes the value of label2. The Code is as follows.
Modify the string value in qml.
//mainpage.qml
Button{
id:btn3
text: qsTr("emit stringchanged signal")
onClicked: myObjectExposeByCXProperty.myString="xxxxx";
}

Qt C ++ Trigger Signal
//myclass.cpp
void MyClass::setmyString(QString aString)
{
if(aString==m_string)
{
return;
}
m_string=aString;
emit myStringChanged();
}

Connect signal handler response
// Mainpage. qml
Connections
{
Target: myObjectExposeByCXProperty
OnMyStringChanged: label2.text = "Signal handler received"
}

Parameters:
Basic Ideas and steps

The basic idea is to expose your Qt C ++ objects to the QML end, connect them using signals-slots, and transmit messages. The procedure is as follows:
1. Create your own object. If your object is to be displayed on the QML side, you can inherit QDeclarativeItem. If it is just a control class, instead of being displayed on the QML side, you only need to inherit QObject. For details about data binding, see Using QML Bindings in C ++ Applications.

# Include <QObject>
Class NetConnectController: public QObject
{
Q_OBJECT
Q_PROPERTY (int status READ status WRITE setStatus reset y 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 different network statuses
Int m_status;
};


2 expose your object to QML

..... 
NetConnectController netController
QDeclarativeEngine * engine = viewer.engine();
(engine->rootContext())->setContextProperty("NetController",&netController);
.....

3. Connect Signal-slot in QML

......
 
Connections
{
target: NetController
onStatusChanged:changeStatus(aStatus)//Call JS Function
}
......

Note: The above onStatusChanged naming format is "on" + "signal name in Qt C ++ ". You can directly use the Qt C ++ parameters on the qml side. For example, the above "aStatus ".

Call the QML function directly in Qt C ++ 

Similarly, QML functions can be called by Qt C ++.
All QML functions expose the Qt C ++ end through the meta-object system. You can use the QMetaObject: invokeMethod () method to directly call the Qt C ++ end. The following is an example.
// 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;

Note: The parameters Q_RETURN_ARG () and Q_ARG () in the QMetaObject: invokeMethod () method are defined as the QVariant type, which is the common data type of the parameters and return values of the QML function.
For more routines, see \ QtSDK \ Examples \ 4.7 \ declarative \ tutorials \ extending in the SDK installation directory.

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.