Namespaces

Variants
Actions

Please note that as of October 24, 2014, the Nokia Developer Wiki will no longer be accepting user contributions, including new entries, edits and comments, as we begin transitioning to our new home, in the Windows Phone Development Wiki. We plan to move over the majority of the existing entries over the next few weeks. Thanks for all your past and future contributions.

Transformations with QWidgets

From Wiki
Jump to: navigation, search
Article Metadata
Code ExampleTested with
Devices(s): N8
Compatibility
Platform(s): Symbian
Symbian
Article
Keywords: QPainter,QMatrix
Created: somnathbanik (26 Apr 2014)
Last edited: hamishwillee (11 Oct 2012)


Contents

Overview

This article shows how to perform transformations on a QWidget. The associated code example draws a circle filled with pattern onto a widget. The user can click on the widget to start and stop it rotating.

TransformationQt.png


TransformationQt class Defination

#ifndef TRANSFORMATIONQT_H
#define TRANSFORMATIONQT_H
 
#include <QMainWindow>
#include <QWidget>
#include <QSize>
 
namespace Ui {
class TransformationQt;
}
 
class TransformationQt : public QWidget
{
Q_OBJECT
 
public:
explicit TransformationQt(QWidget *parent = 0);
~TransformationQt();
 
private:
Ui::TransformationQt *ui;
public:
QSize sizeHint() const {return QSize(200,200);}
protected:
void paintEvent(QPaintEvent *ev);
void mousePressEvent(QMouseEvent *ev);
void timerEvent(QTimerEvent *ev);
void wheelEvent(QWheelEvent *ev);
void rotate(int degree);
private:
int timerId;
int degree;
};
 
#endif // TRANSFORMATIONQT_H

The sizeHint() method defines the initial size of the widget, we re-implement the paintEvent() for drawing, mousePressEvent() for catching mouse clicks, wheelEvent() for reacting to the scroll wheel and rotate() performs the rotation work. For handling the timer we have taken a variable timerId and to make the degree of rotation we have taken another variable degree.

TransformationQt class Implementation

TransformationQt::TransformationQt(QWidget *parent) :
QWidget(parent)
 
{
QRect rect(0,0,360,580);
degree = 0;
timerId = 0;
this->setGeometry(rect);
}

In the constructor we set the values of degree and timerId to zero. And set the window size to 360x580.


void TransformationQt::paintEvent(QPaintEvent* /*ev*/)
{
QRect rect(60,130,220,220);
QRect paintRect = rect;
 
QPoint center = paintRect.center();
paintRect.setWidth(paintRect.height());
paintRect.adjust(2,2,-2,-2);
QPainter p(this);
p.setRenderHint(QPainter::Antialiasing, true);
QMatrix m;
m.translate(center.x(), center.y());
m.rotate(degree);
m.translate(-center.x(), -center.y());
p.setMatrix(m);
 
p.setBrush(QPixmap(":/Qt.png"));
p.setPen(QPen(Qt::black, 2, Qt::DashLine));
p.drawEllipse(paintRect);
}

In the paintEvent() function we create the geometry of the widget. We match the widget of the rectangle of its height and then we adjust the rectangle. After we have initialized the QPainter its time to move on to the transformation matrix which will help us to to make the rotation around the midpoint of the circle. Now we will create a matrix. As the center point is the point between the window, so first we move the center of the window to the zero point of the coordinate system and then we rotate the matrix and move the point back to its original location. Now the matrix that is being generated is passed to the Painter. This will make everything to rotate that is being painted with a number of degrees mentioned in degree variable. We also set the pen with Black color of thickness two pixels and dashed line. And finally we draw with the ellipse into the window, which will draw a circle on the window.


void TransformationQt::mousePressEvent(QMouseEvent* ev)
{
if (ev->button() != Qt::LeftButton)
return;
if ( timerId == 0 )
timerId = startTimer(20);
else {
killTimer(timerId);
timerId = 0;
}
}

As soon as the user clicks the widget, the widget receives the mousePressEvent(). In mousePressEvent() function we check whether the user clicks with the left mouse button or not and then if the value of time is zero then it means that the timer is not running and we can start the timer, or else we need to stop the timer.

void TransformationQt::timerEvent(QTimerEvent *ev)
{
if (ev->timerId() == timerId)
rotate(1);
 
}

We set the timer interval to 20 milliseonds and for each timerEvent() triggered the programs calls the rotate() function. The parameter is set to 1 to make sure that the circle turns by one degree.

void TransformationQt::wheelEvent(QWheelEvent *ev)
{
rotate(ev->delta()/8);
}

The wheelEvent() function is responsible to rotate the circle by a degree in clockwise or counterclockwise depending upon the direction in which the wheel is moved.


void TransformationQt::rotate(int deg)
{
degree = degree + deg % 360;
update();
}

The rotate() function manage the degree value that we use in the paint event. As soon as the value of the degree exceeds to 359 the modulo operator reset the counter to zero. The delta() method in wheelEvent() holds the movement value. Now when we call the update() function it sends a repaintEvent() which cause the widget to be redrawn


Source Code

The full source code presented in this article is available here File:TransformationQt.zip


--somnathbanik

This page was last modified on 11 October 2012, at 01:18.
85 page views in the last 30 days.

Was this page helpful?

Your feedback about this content is important. Let us know what you think.

 

Thank you!

We appreciate your feedback.

×