Showing posts with label masking image. Show all posts
Showing posts with label masking image. Show all posts

Monday, August 16, 2010

Creating custom graphics item in Qt's graphics view

Now a days I started to learn Qt's Graphics view. Initially I was struggling with it but once I started programming with it I found that its quite easy and powerful. What I like most about it is, while creating custom item we can perform paint opration with items local coordinate and need not worry about scene coordinate.

While creating custom graphics item, Your class needs to be derived from QGraphicsItem or QGraphicsObject. If your object needs to use signal/slot than derive your class from QGraphicsObject else derive it from QGraphicsItem and override paint and boundingRect methods.

For test application I tried to create sprite with custom graphics item that shows rolling ball animation. Following is code for my custom graphics item.
#include <QGraphicsObject>
#include <QPixmap>

class BallGraphicsItem : public QGraphicsObject
{
    Q_OBJECT
public:

    BallGraphicsItem();
    ~BallGraphicsItem();

    void paint ( QPainter * painter, 
const QStyleOptionGraphicsItem * option, 
QWidget * widget = 0 );

    QRectF boundingRect() const;

public slots:
    void move();
    void nextFrame();
private:

    QPixmap mBallImage;    
    int mCurrentRow;
    int mCurrentColumn;    
};

#endif // BALLGRAPHICSITEM_H

#include "ballgraphicsitem.h"
#include <QPainter>
#include <math.h>
#include <QBitmap>


BallGraphicsItem::BallGraphicsItem()
    :QGraphicsObject( ),mBallImage(":sphere.bmp"),
mCurrentRow(0),mCurrentColumn(0)
{
    //masking image to make image transperent
    mBallImage.setMask( 
mBallImage.createMaskFromColor(QColor(255,0,255)));    
}

BallGraphicsItem::~BallGraphicsItem()
{}

QRectF BallGraphicsItem::boundingRect() const
{
    return QRectF(0,0,32,32);
}

void BallGraphicsItem::paint ( QPainter *painter, 
const QStyleOptionGraphicsItem */*option*/, QWidget */*widget*/ )
{
    painter->drawPixmap(0,0,mBallImage, 
mCurrentColumn* 32 ,mCurrentRow*32, 32,32);
}

void BallGraphicsItem::nextFrame()
{
    mCurrentColumn = ++mCurrentColumn % 8;
    if( mCurrentColumn == 0 ) {
        mCurrentRow = ++mCurrentRow %4;
    }
}

void BallGraphicsItem::move()
{    
    setPos( x() + 2, y());
    nextFrame();
}

And my main.cpp file looks like following.
#include <QApplication>
#include <QGraphicsView>
#include <QGraphicsScene>
#include <QTimer>
#include "ballgraphicsitem.h"

int main( int argc, char* argv[] )
{
    QApplication app(argc,argv);

    QGraphicsScene scene( 0, 0, 840, 480 );
    QGraphicsView view(&scene);
    view.setRenderHint(QPainter::Antialiasing);
    view.show();

    BallGraphicsItem* ball = new BallGraphicsItem();
    ball->setPos(10,10);
    scene.addItem( ball );

    QTimer *timer = new QTimer(qApp);
    timer->start(1000/30);
    QObject::connect(timer,SIGNAL(timeout()),ball,SLOT(move()));

    return app.exec();
} 
For above code I am using following image, don't know from where I downloaded image.