End to End GUI Development with Qt5
上QQ阅读APP看书,第一时间看更新

QML

Qt Modeling Language (QML) is a hierarchical declarative language for user interface layout with a syntax similar to JavaScript Object Notation (JSON). It can bind to C++ objects via Qt’s meta object system and also supports inline JavaScript. It’s much like HTML or XAML but without the XMLness. If you are someone who likes JSON more than XML, this can only be a good thing!

Go ahead and open up MasterView.qml, and we’ll see what’s going on.

The first thing you’ll see is a couple of import statements. They are similar to #include statements in C++—they bring in pieces of functionality that we want to use in the view. They can be packed and versioned modules as with QtQuick 2.9, or they can be relative paths to local content.

Next, the QML hierarchy begins with a Window object. The scope of the object is represented by the subsequent {}, so everything within the braces is either a property or child of the object.

Properties follow JSON property syntax, of the form key: value. A notable difference is that speech marks are not required unless you are providing a string literal as a value. Here, we are setting the visible property of the Window object to be true and the size of the window to be 640 x 480 pixels, and we are displaying Hello World in the title bar.

Let’s change the title and add a simple message. Replace the Hello World title with Client Management and insert a Text component inside the body of the Window:

Window {
visible: true
width: 640
height: 480
title: qsTr("Client Management")

Text {
text: "Welcome to the Client Management system!"
}
}

Save your changes, and Run qmake and Run the application:

Let’s make MasterController start earning its keep and rather than hard-coding our welcome message in the UI, we’ll obtain it dynamically from our controller.

Edit master-controller.h and add a new public property of the QString type called welcomeMessage, setting it to an initial value:

QString welcomeMessage = "This is MasterController to Major Tom";

You will also need to #include <QString>.

In order to be able to access this member from QML, we need to configure a new property. After the Q_OBJECT macro but before the first public access modifier, add the following:

Q_PROPERTY( QString ui_welcomeMessage MEMBER welcomeMessage CONSTANT )

Here, we are creating a new property of the QString type that QML can access. QML will refer to the property as ui_welcomeMessage and when called, will get (or set) the value in the MEMBER variable called welcomeMessage. We are explicitly setting the value of the variable up front and will not change it, so it will remain CONSTANT.

You can simply name the property welcomeMessage, rather than ui_welcomeMessage. My personal preference is to explicitly name things that are solely intended for UI consumption with a ui_ prefix to differentiate them from member variables and methods. Do whatever works for you.

Head back to MasterView.qml, and we will put this property to use. Change the text property of the Text component to the following:

text: masterController.ui_welcomeMessage

Note how the QML editor recognizes masterController and even offers code completion for it. Now, rather than displaying a string literal as the message, the QML will access the ui_welcomeMessage property of the instance of MasterController we injected into the root context in main(), which will, in turn, get the value of the welcomeMessage member variable.

Build and Run, and you should now see the message coming from the MasterController:

We now have a working mechanism for QML to call into C++ code and get hold of whatever data and business logic we want to provide it. Here, an important thing to note is that our MasterController knows nothing about the existence of MasterView, and this is a key part of the MVC pattern.