Build a Paint Application for Tablet
This article gives an overview of how a basic paint app can be built using QML, QDeclarativeView targeted for MeeGo*. QML is a JavaScript*-like language which gives a rich user interface for your application. You can find more information about the same here: http://wiki.meego.com/QML_tutorials

The Idea
The idea here is to dynamically create a QML element using JavaScript* and embed the same into the root element at a given set of (x,y) coordinates. The (x,y) coordinates here can be obtained from the mouse location. This in the case of a tablet will be your finger location on the screen. The root element which can be a "rectangle" will act as a "canvas" on which you can draw shapes.
We will also add features like color selection, size selection - width of the pen for your drawing.
Basic Setup
MeeGo* SDK for Windows* is being used to develop this application. Installation and setup instructions can be found in the “Quick Reference” section of this article. Qt* Creator, the IDE that comes with MeeGo* SDK, is being used to develop this sample. On a Windows* 7 machine, here are the steps that will allow you to create this app.
"Start" > All Programs > Meego 1.2 SDK > QtCreator
In the QtCreator click on File > New File or Project > Select "Mobile Qt Application" from the list, follow the wizard and create a Project.
You can choose a target here. Instructions on how to set up these targets can be found in the “Quick Reference” section of this article.
We now need to make some updates to the project to use QML for the UI:
delete "mainwindow.ui" from the project list
In mainwindow.cpp remove
#include "ui_mainwindow.h"
update the constructor from
MainWindow::MainWindow(QWidget *parent) : QMainWindow(parent), ui(new Ui::MainWindow)
{
ui->setupUi(this);
}
to
MainWindow::MainWindow(QWidget *parent) : QMainWindow(parent)
{
}
From the File menu select "New File or Project" and from the listing under "Files and Classes" select "QML" on the right hand side, select "QML File", select a file name, and click Finish.
Once the Qml File is added, we need to add the same to the project resources. From the File menu select "New File or Project" and from the listing under "Files and Classes" select "Qt", on the right hand side select "Qt Resource File", select a file name, and click Finish.
Double click on the resource file and add a prefix and the file. I used "/" for my prefix and added "ui.qml".
We will use QDeclarativeView and set the source of the QDeclarativeView to our QML file. To do this we will edit the MainWindow class. But before doing that, we need to make QDeclarative library visible to the project. This can be done by editing the "QMLPaintApp.pro" file and updating the following line:
QT += core gui declarative
Now edit the MainWindow.h and then MainWindow.cpp
MainWindow.h
#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
Add QDeclarativeView *ui as a member variable to the MainWindow class. To get QdeclarativeView support, <QtDeclarative/QDeclarativeView> is needed in the includes section.
MainWindow.cpp
#include "mainwindow.h"
MainWindow::MainWindow(QWidget *parent) :
QMainWindow(parent)
{
ui = new QDeclarativeView;
ui->setSource(QUrl("qrc:/ui.qml"));
ui->setResizeMode(QDeclarativeView::SizeRootObjectToView);
setCentralWidget(ui);
}
MainWindow::~MainWindow()
{
delete ui;
}
In the constructor of MainWindow class, instantiate the QDeclarativeView item and set the source to the QML file.
ui->setSource(QUrl("qrc:/ui.qml"));
"qrc:/ui.qml" // qt resource file location
In the QML file we will now create a drawing canvas item. This will be a rectangle("rect") of size 640 X 480.
import Qt 4.7
Rectangle {
id: rect
width: 640
height: 480
}
To capture the mouse event on this canvas “rect” we need to add mousearea and capture the event “OnMousePositionChanged”. This event will be fired whenever the mouse changes its position.
MouseArea{
anchors.fill:parent
focus:true
onMousePositionChanged:
{
}
}
We have the mouse event and we need to wire this up to a JavaScript* callback function. We will use an external JavaScript* file which will have the callback function.
Right click on the project. In the “General” section select “Text File” and name it functions.js.
Add this JavaScript* file to the resources following the procedure explained above(same as how we added ui.qml).
In the Qml file, import the same and give an alias to functions.js.
import "functions.js" as PaintFunctions
In the JavaScript* file we need to now have a callback function.
var color = 'black'; // color of the pen, here the dynamic rectangle
var width = 50; // width of the pen
var height = 50;/ height of the pen
function paintshape(x,y)
{
var object = Qt.createQmlObject('import Qt 4.7; Rectangle {id: indrect; width:'+width+'; height:'+height+'; color: "'+color+'"; }',
rect, "dynamicSnippet"+x); // create a rectangle on the fly
object.x = x; // set it at a perticular location on the screen
object.y = y;
}
The paintshape will take x,y coordinates of the mouse position and at that given location will add in a dynamic QML element.
Qt.createQmlObject creates an element dynamically and object.x = x; object.y = y; sets the object at the given coordinates. The size and color of the element are declared as global variables in order to make them more dynamic. This will later on help us with changing the color and size of these dynamic rectangles. As of now we will set the color to “black” and the size to “50 X 50”.
We just need to add this callback function to “onMousePositionChanged” event and pass the mouse location.
import Qt 4.7
import "functions.js" as PaintFunctions
Rectangle {
width: 640
height: 480
id: rect
MouseArea{
anchors.fill:parent
focus:true
onMousePositionChanged:
{
PaintFunctions.paintshape(mouseX,mouseY); // callback function call to the mouse position change event
}
}
}
We will now add dynamic color and size selection. As this is targeted to a touch-based device, a tablet, we will use a gesture to capture the color selection. For this we will again use rectangles as buttons. When a "green" rectangle of size "50X50" is tapped, the pen color will change to "green" and size is set to "50X50".

Using GestureArea we will listen to “onTapAndHold” event. When the event gets fired, a callback function “setcolorSize” will be called that updates the global variables (color, height, width) to the selected color and size.
import Qt 4.7
import Qt.labs.gestures 1.0
import "functions.js" as PaintFunctions
Rectangle{
width:700; height:500;
Rectangle{
width:700; height:5; id:toprect
}
Item {
width: 700; height: 500; anchors.topMargin: 20;anchors.top : toprect.bottom;
Rectangle {
width:500; height:100;
id:colorselect;
Grid {
anchors.horizontalCenter: parent.horizontalCenter
columns:9
spacing: 5
Rectangle { color: "blue";
width: 50; height: 50; border.color:"gray"; border.width:2;radius: 20.0;
GestureArea{ anchors.fill:parent; focus: true; onTapAndHold:{ PaintFunctions.setcolorSize("blue",50,50);}}
}
Rectangle { color: "yellow";
width: 50; height: 50; border.color:"gray"; border.width:2;radius: 20.0;
GestureArea{ anchors.fill:parent; focus: true; onTapAndHold:{ PaintFunctions.setcolorSize("yellow",50,50);}}
}
Rectangle { color: "green";
width: 50; height: 50; border.color:"gray"; border.width:2;radius: 20.0;
// callback for tap and hold
GestureArea{ anchors.fill:parent; focus: true; onTapAndHold:{ PaintFunctions.setcolorSize("green",50,50);}}
}
}
}
Rectangle {
id: rect
width: 640
height: 480
anchors.top:colorselect.bottom
anchors.topMargin: 5
MouseArea{
anchors.fill:parent
focus:true
onMousePositionChanged:
{
PaintFunctions.paintshape(mouseX,mouseY);
}
}
}
}
}
var color = 'black';
var width = 50;
var height = 50;
function setcolorSize(c,w,h) {
color = c; // update the color
width = w; //update the width
height = h; //update the height
}
function paintshape(x,y)
{
var object = Qt.createQmlObject('import Qt 4.7; Rectangle {id: indrect; width:'+width+'; height:'+height+'; color: "'+color+'"; }',
rect, "dynamicSnippet"+x);
object.x = x;
object.y = y;
}
That's it! You have a paint application. You can change the color and size of the pen. Happy painting!
Quick References
- Install and configure MeeGo* SDK for Windows*
- MeeGo* Packaging guidelines
- Integrate your app with Intel AppUp™ SDK Suite
Comments
can you publish a tarball of the sources too ?
--
http://rzr.online.fr/q/qt