Search icon CANCEL
Arrow left icon
Explore Products
Best Sellers
New Releases
Books
Videos
Audiobooks
Learning Hub
Conferences
Free Learning
Arrow right icon
Arrow up icon
GO TO TOP
Qt5 C++ GUI Programming Cookbook

You're reading from   Qt5 C++ GUI Programming Cookbook Practical recipes for building cross-platform GUI applications, widgets, and animations with Qt 5

Arrow left icon
Product type Paperback
Published in Mar 2019
Publisher Packt
ISBN-13 9781789803822
Length 428 pages
Edition 2nd Edition
Languages
Tools
Arrow right icon
Authors (2):
Arrow left icon
Lee  Z Eng Lee Z Eng
Author Profile Icon Lee Z Eng
Lee Z Eng
Lee Zhi Eng Lee Zhi Eng
Author Profile Icon Lee Zhi Eng
Lee Zhi Eng
Arrow right icon
View More author details
Toc

Table of Contents (15) Chapters Close

Preface 1. Look-and-Feel Customization with Qt Designer FREE CHAPTER 2. Event Handling - Signals and Slots 3. States and Animations with Qt and QML 4. QPainter and 2D Graphics 5. OpenGL Implementation 6. Using Network and Managing Large Documents 7. Threading Basics - Asynchronous Programming 8. Building a Touch Screen Application with Qt5 9. XML Parsing Made Easy 10. Conversion Library 11. Accessing Databases with SQL Driver and Qt 12. Develop Web Applications using Qt WebEngine 13. Performance Optimization 14. Other Books You May Enjoy

Exposing the QML object pointer to C++

Sometimes, we want to modify the properties of a QML object through C++ scripting, such as changing the text of a label, hiding/showing the widget, or changing its size. Qt's QML engine allows you to register your QML objects to C++ types, which automatically exposes all its properties.

How to do it...

We want to create a label in QML and change its text occasionally. In order to expose the label object to C++, we can do the following steps:

  1. Create a C++ class called MyLabel that extends from the QObject class in mylabel.h:
class MyLabel : public QObject {
Q_OBJECT
public:
// Object pointer
QObject* myObject;
explicit MyLabel(QObject *parent = 0);

// Must call Q_INVOKABLE so that this function can be used in QML
Q_INVOKABLE void SetMyObject(QObject* obj);
}
  1. In the mylabel.cpp source file, define a function called SetMyObject() to save the object pointer. This function will later be called in QML in mylabel.cpp:

void MyLabel::SetMyObject(QObject* obj) {
// Set the object pointer
myObject = obj;
}
  1. In main.cpp, include the MyLabel header and register it to the QML engine using the
    qmlRegisterType() function:
include "mylabel.h"
int main(int argc, char *argv[]) {
// Register your class to QML
qmlRegisterType<MyLabel>("MyLabelLib", 1, 0, "MyLabel");
}
  1. Notice that there are four parameters you need to declare in qmlRegisterType(). Besides declaring your class name (MyLabel), you also need to declare your library name (MyLabelLib) and its version (1.0), which will be used to import your class to QML.
  2. Map the QML engine to our label object in QML and import the class library we defined earlier in step 3 by calling import MyLabelLib 1.0 in our QML file. Notice that the library name and its version number have to match the one you declared in main.cpp, otherwise it will throw an error. After declaring MyLabel in QML and setting its ID as mylabels, call mylabel.SetMyObject(myLabel) to expose its pointer to C/C++ right after the label is initialized:
import MyLabelLib 1.0
ApplicationWindow {
id: mainWindow
width: 480
height: 640
MyLabel {
id: mylabel
}
Label {
id: helloWorldLabel
text: qsTr("Hello World!")
Component.onCompleted: {
mylabel.SetMyObject(hellowWorldLabel);
}
}
}
  1. Wait until the label is fully initiated before exposing its pointer to C/C++, otherwise you may cause the program to crash. To make sure it's fully initiated, call the SetMyObject() function within Component.onCompleted and not in any other functions or event callbacks. Now that the QML label has been exposed to C/C++, we can change any of its properties by calling the setProperty() function. For instance, we can set its visibility to true and change its text to Bye bye world!:
// QVariant automatically detects your data type
myObject->setProperty("visible", QVariant(true));
myObject->setProperty("text", QVariant("Bye bye world!"));
  1. Besides changing the properties, we can also call its functions by calling the following:
QMetaObject::invokeMethod():
QVariant returnedValue;
QVariant message = "Hello world!";
QMetaObject::invokeMethod(myObject, "myQMLFunction", Q_RETURN_ARG(QVariant, returnedValue), Q_ARG(QVariant, message));
qDebug() << "QML function returned:" << returnedValue.toString();
  1. Or, simply, we can call the invokedMethod() function with only two parameters if we do not expect any values to be returned from it:
QMetaObject::invokeMethod(myObject, "myQMLFunction");

How it works...

QML is designed in such a way that it can be expanded through C++ code. The classes in the Qt QML module permit QML objects to be used and operate from C++, and the capability of the QML engine's united with Qt's meta-object system allows C++ functionality to be called directly from QML. To add some C++ data or usage to QML, it should come forward from a QObject-derived class. QML object types could be instituted from C++ and supervised to access their properties, appeal their methods, and get their signal alerts. This is possible because all QML object types are executed using QObject-derived classes, allowing the QML engine to forcibly load and inspect objects through the Qt meta-object system.

You have been reading a chapter from
Qt5 C++ GUI Programming Cookbook - Second Edition
Published in: Mar 2019
Publisher: Packt
ISBN-13: 9781789803822
Register for a free Packt account to unlock a world of extra content!
A free Packt account unlocks extra newsletters, articles, discounted offers, and much more. Start advancing your knowledge today.
Unlock this book and the full library FREE for 7 days
Get unlimited access to 7000+ expert-authored eBooks and videos courses covering every tech area you can think of
Renews at €18.99/month. Cancel anytime