Contents |
This tutorial describes how to create a transparent (or semi-transparent) Qt application with a QML GUI.
Note that I haven't found a way to do this in QML such that the application will display as transparent under the default qmlviewer application shipped with Qt Creator. Therefore, the approach taken here is to write a Qt application similar to the qmlviewer which does create a transparent window, then embed the QML UI in it. This approach was suggested by members of the QML mailing list (see this thread).
Finally, it looks as though Qt Creator 2.1 provides a QML project template which incorporates a custom viewer: http://labs.qt.nokia.com/2010/09/21/qt-quick-tooling/. Before long you will be able to create this type of application much more easily.
Basic understanding of Qt, QML, and Qt Creator: see this overview with pointers to Qt/QML documentation.
For reference, I used Fedora 13 to write this tutorial. I used a Qt Creator build from 2010-11-02, and a Qt build from 2010-11-18.
First, we'll put in place all the project machinery to run a QML file in our own "viewer".
Then we'll make the changes so that the viewer window is semi-transparent.
As a bonus, we'll turn off window decorations to make the application really blend with the background.
mainwindow.ui file (we'll be using QML for the UI).ui.qml file with this:
import Qt 4.7
Rectangle {
width: 640
height: 480
color: "red"
}
.qrc). This enables binary files to be added to the application executable in a platform-independent way, as well as providing access via a resource name.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.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
MainWindow class.
mainwindow.h. The change here is to make the ui member variable an instance of QDeclarativeView:
#ifndef MAINWINDOW_H
#define MAINWINDOW_H
#include <QMainWindow>
#include <QtDeclarative/QDeclarativeView>
namespace Ui {
class MainWindow;
}
class MainWindow : public QMainWindow
{
Q_OBJECT
public:
explicit MainWindow(QWidget *parent = 0);
~MainWindow();
private:
QDeclarativeView *ui;
};
#endif // MAINWINDOW_H
Note that we also added an include for the <QtDeclarative/QDeclarativeView> header at the top of the file.
mainwindow.cpp file, so that the constructor for the MainWindow loads the QML file (via the Qt Resource mechanism):
#include "mainwindow.h"
MainWindow::MainWindow(QWidget *parent) :
QMainWindow(parent)
{
ui = new QDeclarativeView;
ui->setSource(QUrl("qrc:/ui.qml"));
setCentralWidget(ui);
}
MainWindow::~MainWindow()
{
delete ui;
}
It should now be possible to run the application (click on the big green arrow, bottom-left corner), which should display as a red rectangle:
ui.qml slightly more interesting:
import Qt 4.7
Rectangle {
width: 640
height: 480
color: "#7bffff00"
Text {
text: "I'm walking in the air"
anchors.centerIn: parent
}
}
Note here that the color property is set to an RGBA (color with alpha) string, similar to the hexadecimal color strings used to define HTML colors. The alpha component is defined by the first two digits after the hash symbol (7b), in this case setting the alpha component to 123 (to make it completely transparent, set this to 00; for completely opaque, set it to ff). The other digits define a yellow color for the rectangle.
MainWindow underneath the pale yellow, semi-transparent rectangle. The solution is to modify mainwindow.cpp, so that the constructor sets the main window itself to be transparent:
#include "mainwindow.h"
MainWindow::MainWindow(QWidget *parent) :
QMainWindow(parent)
{
/* you need both these lines for a transparent main window */
setAttribute(Qt::WA_TranslucentBackground);
setStyleSheet("background:transparent;");
ui = new QDeclarativeView;
ui->setSource(QUrl("qrc:/ui.qml"));
setCentralWidget(ui);
}
MainWindow::~MainWindow()
{
delete ui;
}
Now when you run the application, it should look something like this:
A couple of things to note:
If you want to make your application run without window decorations, so it really blends with the background, add a setWindowsFlags(Qt::FramelessWindowHint) method call to the MainWindow constructor:
#include "mainwindow.h"
MainWindow::MainWindow(QWidget *parent) :
QMainWindow(parent)
{
setAttribute(Qt::WA_TranslucentBackground);
setStyleSheet("background:transparent;");
/* turn off window decorations */
setWindowFlags(Qt::FramelessWindowHint);
ui = new QDeclarativeView;
ui->setSource(QUrl("qrc:/ui.qml"));
setCentralWidget(ui);
}
MainWindow::~MainWindow()
{
delete ui;
}
Just for fun, here is the app running with transparent background and no window decorations on MeeGo netbook (under the mutter compositor):