Meego Wiki
Views

QML/Full-screen applications

From MeeGo wiki
(Difference between revisions)
Jump to: navigation, search
(Creating a QML "viewer")
m (+cats)
 
(8 intermediate revisions not shown)
Line 6: Line 6:
* How to maximize an application window
* How to maximize an application window
-
* How to show an application in "true" fullscreen (possibly obscuring desktop toolbars, and without window decorations)
+
* How to show an application in "true" fullscreen (possibly obscuring desktop toolbars, and without window decorations)  
It doesn't cover every single aspect of window sizing in Qt/QML: there's no coverage of setting window x,y position, tracking changes to window geometry etc.
It doesn't cover every single aspect of window sizing in Qt/QML: there's no coverage of setting window x,y position, tracking changes to window geometry etc.
Line 48: Line 48:
   Text {
   Text {
     text: "I'm walking in the air"
     text: "I'm walking in the air"
-
     anchors.horizontalCenter: parent.horizontalCenter
+
     anchors.centerIn: parent
-
    anchors.verticalCenter: parent.verticalCenter
+
   }
   }
}
}
Line 99: Line 98:
#endif // MAINWINDOW_H
#endif // MAINWINDOW_H
</pre>
</pre>
-
Note that we also added an include for the <code>&lt;QtDeclarative/QDeclarativeView&gt;</code> and <code>&lt;QDesktopWidget&gt;</code> headers at the top of the file. Also note that we pass a <code>QDesktopWidget</code> pointer to the <code>MainWindow</code> constructor: this enables us to use the <code>QDesktopWidget</code> instance associated with the application to set properties on the QML viewer if required. <code>QDesktopWidget</code> "provides access to screen information on multi-head systems" (http://doc.trolltech.com/4.7/qdesktopwidget.html#details). This makes it easier to figure out how much screen real estate is available to our application.
+
Note that we also added an include for the <code>&lt;QtDeclarative/QDeclarativeView&gt;</code> and <code>&lt;QDesktopWidget&gt;</code> headers at the top of the file. Also note that we pass a <code>QDesktopWidget</code> pointer to the <code>MainWindow</code> constructor: this enables us to use the <code>QDesktopWidget</code> instance associated with the application to set size properties on the QML viewer. <code>QDesktopWidget</code> "provides access to screen information on multi-head systems" (http://doc.trolltech.com/4.7/qdesktopwidget.html#details); this makes it easier to figure out how much screen real estate is available to our application.
</li>
</li>
Line 122: Line 121:
</li>
</li>
-
<li>Finally, we need to construct a <code>MainWindow.cpp</code> instance in the <code>main.cpp</code> file, passing the application's <code>QDesktopWidget</code> into it:
+
<li>Finally, we need to construct a <code>MainWindow</code> instance in the <code>main.cpp</code> file, passing the application's <code>QDesktopWidget</code> into it:
<pre>
<pre>
Line 201: Line 200:
One last caveat: although the code above works consistently on my two devices (a MeeGo 1.1 netbook and a Fedora 13 laptop), some [http://wiki.forum.nokia.com/index.php/CS001625_-_Connecting_Qt_signal_to_QML_function sample code] I've seen suggests that you may need to conditionally use the <code>QMainWindow</code> methods, depending on the platform you're deploying to. So I recommend you experiment a bit and test on all your target platforms.
One last caveat: although the code above works consistently on my two devices (a MeeGo 1.1 netbook and a Fedora 13 laptop), some [http://wiki.forum.nokia.com/index.php/CS001625_-_Connecting_Qt_signal_to_QML_function sample code] I've seen suggests that you may need to conditionally use the <code>QMainWindow</code> methods, depending on the platform you're deploying to. So I recommend you experiment a bit and test on all your target platforms.
 +
 +
[[Category:tutorial]]
 +
[[Category:qml]]

Latest revision as of 08:46, 31 December 2010

Contents

Overview

This tutorial covers how to configure a QML application to occupy the whole screen (or the whole of one screen in a multi-screen setup).

It also describes other aspects of Qt/QML and screen geometry, such as:

  • How to maximize an application window
  • How to show an application in "true" fullscreen (possibly obscuring desktop toolbars, and without window decorations)

It doesn't cover every single aspect of window sizing in Qt/QML: there's no coverage of setting window x,y position, tracking changes to window geometry etc.

Pre-requisites

Qt Creator (MeeGo 1.1 SDK version) installed. See these instructions.

System Setup

No special system setup is required.

How to

The first step is to create a simple "viewer" for the QML application, written in Qt. This will load the QML file.

Then we set some properties on the viewer so it will fill the whole screen (optionally, in a maximized window or true fullscreen).

Creating a QML "viewer"

  1. Create a new project using Qt Creator: Qt C++ Project, Mobile Qt Application is a good basis.
  2. In the project, delete the mainwindow.ui file (we'll be using QML for the UI).
  3. Next, create a (very) simple QML user interface file:
    1. Right-click on the project name, and select Add New... from the context menu.
    2. In the dialog box, select Qt then Qt QML File.
    3. Click Choose.
    4. Enter ui as the name of the file.
    5. Click Next, accept the defaults, and click Finish.
    6. Replace the content of the new ui.qml file with this:
      import Qt 4.7
      
      Rectangle {
        color: "#7bffff00"
      
        Text {
          text: "I'm walking in the air"
          anchors.centerIn: parent
        }
      }
      

      Note that I haven't set a height and width on the top-level Rectangle in this file, as these will be derived from the window that the QML UI is embedded within.

  4. Next we need a way to locate the QML file from the Qt application. To do this, we'll add a Qt resource file (.qrc). This enables binary files to be added to the application executable in a platform-independent way, as well as providing access to them via resource names.
    Add the resource file as follows:
    1. Right-click on the project, choose Add New..., and select Qt, Qt Resource file.
    2. Step through the dialog boxes. Use resources for the file name.
    3. Once the file is ready, click on the Add button and select Add Prefix from the drop-down. Use / as the prefix.
    4. Still in the resources.qrc file, click the Add button again and select Add Files. This pops up a file chooser: inside it, click on the ui.qml file and then click Open. The selected file should should now appear under the / prefix.
  5. Now the application needs to be able to use classes from the QDeclarative library. To make this library visible to the project, edit the .pro file for your project, adding declarative to the QT line, like this:
    QT += core gui declarative
    
  6. To load the QML file, we'll modify the existing MainWindow class.
    1. First edit the header file, mainwindow.h. The changes here are to make the ui member variable an instance of QDeclarativeView; and to pass a QDesktopWidget into the constructor, rather than a QWidget.:
      #ifndef MAINWINDOW_H
      #define MAINWINDOW_H
      
      #include <QMainWindow>
      #include <QtDeclarative/QDeclarativeView>
      #include <QDesktopWidget>
      
      class MainWindow : public QMainWindow
      {
        Q_OBJECT
      
      public:
        explicit MainWindow(QDesktopWidget *parent);
        ~MainWindow();
      
      private:
        QDeclarativeView *ui;
      };
      
      #endif // MAINWINDOW_H
      

      Note that we also added an include for the <QtDeclarative/QDeclarativeView> and <QDesktopWidget> headers at the top of the file. Also note that we pass a QDesktopWidget pointer to the MainWindow constructor: this enables us to use the QDesktopWidget instance associated with the application to set size properties on the QML viewer. QDesktopWidget "provides access to screen information on multi-head systems" (http://doc.trolltech.com/4.7/qdesktopwidget.html#details); this makes it easier to figure out how much screen real estate is available to our application.

    2. Next, edit the mainwindow.cpp file, so that the constructor for the MainWindow loads the QML file (via the Qt Resource mechanism):
      #include "mainwindow.h"
      
      MainWindow::MainWindow(QDesktopWidget *parent) :
        QMainWindow(parent)
      {
        this->ui = new QDeclarativeView;
        this->ui->setSource(QUrl("qrc:/ui.qml"));
        setCentralWidget(this->ui);
      }
      
      MainWindow::~MainWindow()
      {
        delete this->ui;
      }
      
  7. Finally, we need to construct a MainWindow instance in the main.cpp file, passing the application's QDesktopWidget into it:
    #include "mainwindow.h"
    #include <QApplication>
    
    int main(int argc, char *argv[])
    {
      QApplication a(argc, argv);
    
      MainWindow w(a.desktop());
      w.show();
    
      return a.exec();
    }
    

Note that this code will run but won't display the yellow rectangle, as it has no size properties set.

Configuring the viewer's window size

There are two parts to configuring the application to fill the screen:

  1. Use QDeclarativeView::setResizeMode(QDeclarativeView::SizeRootObjectToView) on the QDeclarativeView (the object which loads the QML file). This makes the QDeclarativeView automatically resize the root element (defined in the QML file) so that it always fills the MainWindow it's running inside. In our case, this means resizing the top-level Rectangle to fill the MainWindow.
  2. Resize the MainWindow using methods from the QMainWindow class. There are several possible approaches:
    1. Use showMaximized() to maximize the window so it fills the default screen. This respects features such as toolbars which are permanently on the desktop and ensures that they aren't obscured.
    2. Use showFullScreen() to set the application truly full screen. In this case, the application will be displayed without window decorations, and will potentially obscure desktop toolbars.
    3. Use setGeometry(desktop->availableGeometry()) to set the MainWindow to the same size as the default screen. The window will appear maxmimized, but will actually be resizable. Note that the availableGeometry() method takes into account desktop features like toolbars.
    See http://doc.trolltech.com/4.7/qdesktopwidget.html#screen-geometry for more information about screen geometry in Qt.

Below is an example of how to maximize the MainWindow and resize the top-level Rectangle to fill it:

#include "mainwindow.h"

MainWindow::MainWindow(QDesktopWidget *desktop) :
  QMainWindow(desktop)
{
  this->ui = new QDeclarativeView;
  this->ui->setSource(QUrl("qrc:/ui.qml"));

  /* resize the root object in the QML UI definition
   * to fill the window; the alternative (and default) setting
   * is SizeViewToRootObject, which sizes
   * the view to the top-level QML element
   */
  this->ui->setResizeMode(QDeclarativeView::SizeRootObjectToView);

  /* maximize window */
  showMaximized();

  /* alternative approaches:
   *
   * - showFullScreen()
   *   makes the application truly full screen, without
   *   window decorations
   *
   * - setGeometry(desktop->availableGeometry())
   *   makes the application fill the default screen,
   *   but not maximized
   */

  setCentralWidget(this->ui);
}

MainWindow::~MainWindow()
{
    delete this->ui;
}

It looks like this on a MeeGo netbook:

Qml-maximized-on-meego.png

One last caveat: although the code above works consistently on my two devices (a MeeGo 1.1 netbook and a Fedora 13 laptop), some sample code I've seen suggests that you may need to conditionally use the QMainWindow methods, depending on the platform you're deploying to. So I recommend you experiment a bit and test on all your target platforms.

Personal tools