summaryrefslogtreecommitdiffstats
path: root/desktop_devguide/chapter_07/step_1.rst
blob: ba8c5577aa7be25eabbe00cb20fa87c4d0e336a6 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
..
    ---------------------------------------------------------------------------
    Copyright (C) 2012 Digia Plc and/or its subsidiary(-ies).
    All rights reserved.
    This work, unless otherwise expressly stated, is licensed under a
    Creative Commons Attribution-ShareAlike 2.5.
    The full license document is available from
    http://creativecommons.org/licenses/by-sa/2.5/legalcode .
    ---------------------------------------------------------------------------

Creating the NoteApp Qt Application
===================================

The goal is to create a single executable     NoteApp* binary file that the user will just run to get *NoteApp* loaded.

Let's see how we can use Qt Creator for this.


Creating a Qt Quick Application
-------------------------------

First we need to create a :creator:`Qt Quick Application <quick-projects.html#creating-qt-quick-applications>` using Qt Creator and make sure that we have selected     *Built-in elements only (for all platforms)** in the Qt Quick Application wizard. Let's name the application *noteapp*.

So now we have a newly created project from the wizard and we notice that a     qmlapplicationviewer* project is generated for us. The generated *qmlapplicationviewer* project is a basic 'template' application that loads QML files.  This application, as being a very generic one for deploying Qt Quick applications across devices and targets, includes several platform specific code for each of those deployment targets. We will not go through these specific parts of the code because it doesn't fit the purpose of this guide.

Nevertheless, there are certain peculiarities of the     qmlapplicationviewer* that somewhat limit us to achieve what we want. The application expects the developer to ship the QML files along with with the executable binary. Using the Qt Resource System becomes impossible, but you will see how to overcome this problem as we proceed.

For the     noteapp* project, there is just one CPP source file, `main.cpp`. In the `main.cpp` file, you will see how the `viewer` object, the `QmlApplicationViewer` class, is used to load the `main.qml` file by calling the `QmlApplicationViewer::setMainQmlFile()` function.


.. code-block:: cpp

  // main.cpp
  ...
  Q_DECL_EXPORT int main(int argc, char     argv[])
  {
      QScopedPointer<QApplication> app(createApplication(argc, argv));
      QScopedPointer<QmlApplicationViewer> viewer(
                  QmlApplicationViewer::create());

      viewer->setOrientation(QmlApplicationViewer::ScreenOrientationAuto);
      viewer->setMainQmlFile("qml/noteapp/main.qml");
      viewer->showExpanded();

      return app->exec();
  }


Note, there is a basic `main.qml` file generated by the Qt Quick Application wizard which will be replaced by the `main.qml` file we have created for     NoteApp*.

The folder structure of the generated     noteapp* project is very straightforward to understand.

     noteapp - root folder of the *noteapp* project

       qml - this folder contains all the QML files
       qmlapplicationviwer - the generated application used for loading QML files
       noteapp.pro - the project file
       main.cpp - the C++ file where a Qt Application is created that will produce a binary file for us

We need to copy our QML files including the `fonts` and `images` directories in the `qml` directory of the newly created     noteapp* project. Additionally, we need to import these files into the project so that we will be able to work with them in Qt Creator.

.. image:: img/importqmlfiles.png
    :scale: 80%
    :align: center

.. note:: Make sure to add all existing files including images called from the `nodeDDB.js` file

At this point, let's start to build and run the project and see if everything has gone well with the project creation. Before building the     noteapp* project, let's make sure we have the right settings in place for our project. Please refer to :creator:`Configure Projects <creator-configuring-projects.html>` in Qt Creator documentation.

Once the application is successfully built, an executable binary file called `noteapp` should be produced in the root folder of the project. If you have Qt configured properly for your system, you'll be able run the file by clicking on it.


Using Qt Resource System to Store QML Files and Images
------------------------------------------------------

We have created an executable that loads the QML file for the application to run. As you can see in the `main.cpp` file, the `viewer` object loads the `main.qml` file by passing the relative path of that file. Additionally, we open the `noteapp.pro` file to understand deployment and build settings so we notice the first lines:

.. code-block:: bash

  # Add more folders to ship with the application, here
  folder_01.source = qml/noteapp
  folder_01.target = qml
  DEPLOYMENTFOLDERS = folder_01

  ....

Seems that it is expected to actually ship the QML files along with the executable file, but this is not what we would like to achieve.

Qt provides a quite intuitive :qt:`Resource System <resources.html>` that works seamlessly with QML. We need to create a resource file, `noteapp.qrc` for the     noteapp* root project so that we can add our QML and image files in it. Please refer to the :qt:`Creating a Resource File <creator-writing-program.html#creating-a-resource-file>` in Qt Creator documentation for detailed steps.

.. image:: img/resourcefile.png
    :scale: 100%
    :align: center

We need to apply minor changes to the `noteapp.pro` and the `main.cpp` in order to be able to use the newly created resource file, `noteapp.qrc`.

First we comment out the first lines in the `noteapp.pro`:

.. code-block:: bash

  # Add more folders to ship with the application, here
  #folder_01.source = qml/noteapp
  #folder_01.target = qml
  #DEPLOYMENTFOLDERS = folder_01

  ....

In addition to that, we can remove the following lines from the `noteapp.pro` file since they are Symbian platform related.

.. code-block:: bash

  ...
  symbian:TARGET.UID3 = 0xE68D5D88
  ...
  # Allow network access on Symbian
  symbian:TARGET.CAPABILITY += NetworkServices
  ...


In the `main.cpp` file, we see the `QmlApplicationViewer::setMainQmlFile()` function being called with the relative path to the `main.qml` file.

.. code-block:: cpp

  // qmlapplicationviewer.cpp
  ...
  void QmlApplicationViewer::setMainQmlFile(const QString &file)
  {
      d->mainQmlFile = QmlApplicationViewerPrivate::adjustPath(file);
      setSource(QUrl::fromLocalFile(d->mainQmlFile));
  }
  ...


The `QmlApplicationViewer` class inherits :qt:`QDeclarativeView <qdeclarativeView.html>`, which is a convenient class for loading and displaying QML files. The `QmlApplicationViewer::setMainQmlFile()` function is not optimized for using resources because it adjusts the path of the QML file before calling the :qt:`setSource() <qdeclarativeview.html#source-prop>` function.

The simplest approach to overcome this would be to directly call :qt:`setSource() <qdeclarativeview.html#source-prop>` on the  `viewer` object in the `main.cpp` file, but this time we pass the `main.qml` as part of the resource file.

.. code-block:: cpp

  // main.cpp
  ...
  Q_DECL_EXPORT int main(int argc, char     argv[])
  {
      QScopedPointer<QApplication> app(createApplication(argc, argv));
      QScopedPointer<QmlApplicationViewer> viewer(
                  QmlApplicationViewer::create());

      viewer->setOrientation(QmlApplicationViewer::ScreenOrientationAuto);
      viewer->setSource(QUrl("qrc:/main.qml"));
      viewer->showExpanded();

      return app->exec();
  }

There is no other change to be done in the QML files where we use the image files and the font file since the path of the files is a relative one, which will point to the resource internal filesystem. So now we can build the project in Qt Creator that will produce us a binary executable file that bundles all the QML files, images and the font.

Let's try to make a build and see how that works!


Setting an Application Icon and Title
-------------------------------------

A graphical enhancement that is highly recommended is to set an icon for the application, which will uniquely identify your application when deployed in a desktop platform.

Inside the     noteapp* folder, you may have noticed a few *PNG* files and one *SVG* file by now. These image files will be used to set the icon for the application depending on the icon size since we can have 64x64 or 80x80 icons or a vectorized one.

For more details concerning how these icon files are deployed on various platforms, you need to take a close look at the `qmlapplicationviewer.pri` file. You can find find detailed information on application icons in the :qt:`How to Set the Application Icon <appicon.html>` Qt reference documentation.

We need to call the :qt:`setWindowIcon() <qwidget.html#windowIcon-prop>` function on the `viewer` in order to set the icon for the application window.

.. code-block:: cpp

  // main.cpp
  ...
  QScopedPointer<QApplication> app(createApplication(argc, argv));
  QScopedPointer<QmlApplicationViewer> viewer(
              QmlApplicationViewer::create());

  viewer->setWindowIcon(QIcon("noteapp80.png"));
  ...

We need a default window-title for our application and we will use the :qt:`setWindowTitle() <qwidget.html#windowTitle-prop>` function for this.

.. code-block:: cpp

  // main.cpp
  ...

  QScopedPointer<QApplication> app(createApplication(argc, argv));
  QScopedPointer<QmlApplicationViewer> viewer(
              QmlApplicationViewer::create());

  viewer->setWindowIcon(QIcon("noteapp80.png"));
  viewer->setWindowTitle(QString("Keep Your Notes with NoteApp!"));
  ...


The     NoteApp* is now ready to be shipped and deployed onto various desktop platforms.

Deploying NoteApp
-----------------

    NoteApp* is a typical Qt application so you need to decide whether you would like to statically or dynamically link against Qt. Additionally, every desktop platform has specific linking configurations to be considered.

You can find detailed information on :qt:`Deploying Qt Applications <deployment.html>` reference documentation for each deployment desktop target.


.. rubric:: What's Next?

A summary of what we have learned in this developer guide.