Tuesday 24 December 2013

Make a Qt Quick UI project

I introduced how to create a Qt Quick project using Qt Creator, it's a basic project. But most of time, I want the Qt UI designed by qml will be kept separate from C++ code. UI designer edits the .qml files, C++ code loads them in runtime, then binds events and handles events like HTML.
This article, I will show how to do this.

First, let's design a qml file which represents a simple tab view window.
In main.qml file, add below qml statements:
import QtQuick 2.1
import QtQuick.Window 2.1
import QtQuick.Controls 1.1
import QtQuick.XmlListModel 2.0
Window {
    width: 538 + frame.margins * 2
    height: 360 + frame.margins * 2
    ToolBar {
        id: toolbar
        width: parent.width
    }
    SystemPalette {id: syspal}
    color: syspal.window

    Rectangle {
        anchors.top: toolbar.bottom
        anchors.right: parent.right
        anchors.left: parent.left
        anchors.bottom:  parent.bottom
        anchors.margins: 8
        TabView {
            id:frame
            focus:true
            property int margins: Qt.platform.os === "osx" ? 16 : 0
            height: parent.height - 34
            anchors.right: parent.right
            anchors.left: parent.left
            anchors.margins: margins
            Tab {
                title: "Home"
            }
            Tab {
                title: "Edit"
            }
            Tab {
                title: "View"
            }
            Tab {
                title: "Help"
            }
        }
    }
}
We can use qmlscene tool for testing qml file. Execute the following command
qmlscene main.qml
qmlscene: could not find a Qt installation of ''
I see the error because my Ubuntu have installed different versions of Qt. Need to point to the full path of my qmlscene like this:
 ~/Qt5.2.0/5.2.0/gcc_64/bin/qmlscene main.qml

A window pops up now.

Second, create a Qt C++ project to load qml file.
My project folder tree looks like so:
.
├── gui.pro
├── images
│   ├── header.png
│   └── selectedrow.png
├── main.qml
├── resources.qrc
└── src
    ├── main.cpp
    └── src.pri

the gui,pro file has content as following
QT += qml quick
TARGET = gui
!android: !ios: !blackberry: qtHaveModule(widgets): QT += widgets
include(src/src.pri)
OTHER_FILES += \
    main.qml
RESOURCES += \
    resources.qrc
HEADERS +=
the resources.qrc file, to get more information about qrc, see http://doc-snapshot.qt-project.org/qdoc/resources.html
<!DOCTYPE RCC><RCC version="1.0">
<qresource prefix="/">
  <file>main.qml</file>
  <file>images/selectedrow.png</file>
  <file>images/header.png</file>
</qresource>
</RCC>
the src.pri file
SOURCES += \
    $$PWD/main.cpp
 Ok. have  a look at the key file: src/main.cpp
#include <QtQml>
#include <QtQuick/QQuickView>
#include <QtCore/QString>
#ifdef QT_WIDGETS_LIB
#include <QtWidgets/QApplication>
#else
#include <QtGui/QGuiApplication>
#endif

#ifdef QT_WIDGETS_LIB
#define Application QApplication
#else
#define Application QGuiApplication
#endif
int main(int argc, char *argv[])
{
    Application app(argc, argv);
    QQmlApplicationEngine engine(QUrl("qrc:/main.qml"));
    QObject *topLevel = engine.rootObjects().value(0);
    QQuickWindow *window = qobject_cast<QQuickWindow *>(topLevel);
    if ( !window ) {
        qWarning("Error: Your root item has to be a Window.");
        return -1;
    }
    window->show();
    return app.exec();
}
In the main function, Create QmlAppliationEngine to load qml file, then get top level QObject from engine and show it as a window object.

Finally, you can open the gui.pro with Qt Creator and run it. Alternatively, you can run qmake to generate Makfile and make it.

No comments:

Followers

Contributors