PDA

View Full Version : GraphicsItem is flickering



anafor2004
30th September 2009, 10:41
Dear Friends,
I have a problem with setPos() function in QGraphicsItem class, I have created my own GraphicsItem class derived from QGraphicsItem. I loaded Iems in a Scene. Now I am locating Items, and trying to slide some pictures, but pictures are flickering.

I am using a QTimer and it's slot for moving pictures, setPos() function .

How can I prevend this problem.

wysota
30th September 2009, 10:54
Please provide a minimal compilable example reproducing the problem.

anafor2004
30th September 2009, 11:15
GraphicsItem.cpp


#include "GraphicItem.h"

GraphicItem::GraphicItem(QPixmap image)
{
// TODO Auto-generated constructor stub
myWidth = 150;
myHeight =150;
m_Selected = false;
Org = image;
makePhoto(Org);
makeReflection();
}

GraphicItem::GraphicItem()
{
myWidth = 150;
myHeight =150;
m_Selected = false;
Org = NULL;
makePhoto(Org);
makeReflection();
}
GraphicItem::~GraphicItem() {
// TODO Auto-generated destructor stub
}


QRectF GraphicItem::boundingRect() const
{
return QRectF(0.0f,0.0f,myWidth,myHeight);
}


void GraphicItem::SelectedStatus(bool Selected)
{
m_Selected = Selected;
makePhoto(Org);
makeReflection();
}

void GraphicItem::MoveLeft()
{
SetRightPlace(pos().x()+200,pos().y());
}

void GraphicItem::MoveRight()
{
SetRightPlace(pos().x()-200,pos().y());
}

void GraphicItem::SetRightPlace(int x,int y)
{
RightX = x;
RightY = y;
}

bool GraphicItem::IsRightPlace()
{
return(RightX == pos().x()) && (RightY == pos().y());
}

void GraphicItem::Animate()
{
int x = pos().x();
int y = pos().y();

int dx = 6;
int dy = 6;

if(pos().x() < RightX)
{
if((pos().x() + dx >= RightX))
x = RightX;
else
x = pos().x() + dx;
}
else if(pos().x() > RightX)
{
if((pos().x() - dx <= RightX))
x = RightX;
else
x = pos().x() - dx;
}

if(pos().y() < RightY)
{
if((pos().y() + dy >= RightY))
y = RightY;
else
y = pos().y() + dy;
}
else if(pos().y() > RightY)
{
if((pos().y() - dy <= RightY))
y = RightY;
else
y = pos().y() - dy;
}
setPos(x,y);
}


void GraphicItem::ChangePixmap(QPixmap pixmap)
{
Org = pixmap;
makePhoto(Org);
makeReflection();
}

void GraphicItem::paint(QPainter* painter,const QStyleOptionGraphicsItem*,
QWidget*)
{
printf("void GraphicItem::paint\n");
painter->drawPixmap(0,0,item);
painter->drawPixmap(0,static_cast<int>(myHeight*0.5f),itemMirror);
}

void GraphicItem::makePhoto(QPixmap image)
{
item = QPixmap(myWidth,static_cast<int>(myHeight*0.5f));
if((image.width() > myWidth - 2) || (image.height() > myHeight*0.5f-2))
image = image.scaled(myWidth-2,static_cast<int>(myHeight*0.5f-2),
Qt::KeepAspectRatio,Qt::SmoothTransformation);
QPainter* painter = new QPainter(&item);
QPen pen;
if(m_Selected)
pen.setBrush(Qt::red);
else
pen.setBrush(Qt::darkGray);

pen.setWidth(5);
painter->setPen(pen);
QLinearGradient gradient;
gradient = QLinearGradient(0,0,0,static_cast<int>(myHeight*0.5f));
gradient.setColorAt(0.0f,QColor(175,175,175));
gradient.setColorAt(0.5f,QColor(215,215,215));
gradient.setColorAt(1.0f,QColor(175,175,175));
painter->setBrush(QBrush(gradient));
painter->drawRect(0,0,myWidth,static_cast<int>(myHeight*0.5f));
painter->drawPixmap(static_cast<int>(myWidth*0.5f-(image.width()*0.5f)),
static_cast<int>(myHeight*0.25f-(image.height()*0.5f)),
image);
delete painter;
}

void GraphicItem::makeReflection()
{
itemMirror = QPixmap(myWidth,static_cast<int>(myHeight*0.5f));
QPainter* painter = new QPainter(&itemMirror);
painter->drawPixmap(0,0,QPixmap::fromImage(item.toImage()
.mirrored(false,true)));
painter->resetTransform();
QPen pen(Qt::transparent);
painter->setPen(pen);
QLinearGradient gradient;
gradient = QLinearGradient(0,0,0,static_cast<int>(myHeight*0.375f));
gradient.setColorAt(0.0f,QColor(0,15,15,155));
gradient.setColorAt(1.0f,QColor(0,15,15,255));
painter->setBrush(QBrush(gradient));
painter->drawRect(0,0,myWidth,static_cast<int>(myHeight*0.5f));
delete painter;
}

GraphicsItem.h


/*
* GraphicItem.h
*
* Created on: Sep 29, 2009
* Author: root
*/

#ifndef GRAPHICITEM_H_
#define GRAPHICITEM_H_

#include <QGraphicsItem>
#include <QGraphicsScene>
#include <QPixmap>
#include <QImage>
#include <QLinearGradient>
#include <QPainter>

class GraphicItem : public QGraphicsItem
{
public:
GraphicItem(QPixmap image);
GraphicItem();
virtual ~GraphicItem();

QRectF boundingRect() const;
void paint(QPainter* painter,const QStyleOptionGraphicsItem* option,
QWidget* widget);

void SelectedStatus(bool Selected);
void ChangePixmap(QPixmap pixmap);

void MoveRight();
void MoveLeft();

void SetRightPlace(int x,int y);
bool IsRightPlace();
void Animate();

public:
bool m_Selected;
int RightX;
int RightY;
int myWidth;
int myHeight;
//Pixmap's for drawing methods
QPixmap Org; // Original Pixmap
QPixmap item; // Scaled and Framed
QPixmap itemMirror; // Mirrored


void makePhoto(QPixmap Image);
void makeReflection();
};

#endif /* GRAPHICITEM_H_ */


TestView derived from QGraphicsView


#pragma once

#include "GenericView.h"
#include "ITestView.h"
#include "ITestCallBack.h"
#include "GraphicItem.h"
#include <QTimer>

class TestView : public GenericView , public ITestView
{
Q_OBJECT
public:
TestView();
virtual~TestView();
void SetCallBack(ITestCallBack *CallBack);
void SetIndex(int Indx);
int GetIndex();
void SetList(std::list <Media> Liste);
void ShowView();

private:
std::vector <GraphicItem*> Items;
std::vector <GraphicItem*>::iterator Itr;

int SelectIndx;
void Key_Right();
void Key_Left();
void LoadData(std::list <Media> Liste);
void LoadMenuItems(int Indx);
void GetXYData(int Indx);
QPoint *points;
QTimer* timer;
QTimer* timer2;

ITestCallBack *callback;
std::list <Media> _Liste;

public slots:
void Animate();


protected:
void showEvent(QShowEvent* event);
};





#include "TestView.h"
#include <QPixmap>

TestView::TestView()
{
timer = new QTimer(this);
timer->setInterval(15);
connect(timer,SIGNAL(timeout()),this,SLOT(Animate( )));

}

TestView::~TestView()
{
delete callback;
}



void TestView::Key_Right()
{
callback->Key_RightPressed();
}

void TestView::Key_Left()
{
callback->Key_LeftPressed();
}

void TestView::SetCallBack(ITestCallBack *CallBack)
{
callback = CallBack;
}

void TestView::SetIndex(int Indx)
{
if(Indx < Items.size() && Indx >= 0)
{
if(!timer->isActive())
{
if(Indx > SelectIndx)
{
for(int i=0;i<Items.size();i++)
Items[i]->MoveRight();

}
else if(Indx < SelectIndx)
{
for(int i=0;i<Items.size();i++)
Items[i]->MoveLeft();
}

SelectIndx = Indx;
timer->start();
}
}
}
int TestView::GetIndex()
{
return SelectIndx;
}

void TestView::SetList(std::list <Media> Liste)
{
_Liste = Liste;
LoadData(_Liste);
}
void TestView::ShowView()
{
show();
}

void TestView::showEvent(QShowEvent* event)
{
if(!timer->isActive())
timer->start();
}

void TestView::LoadData(std::list <Media> Liste)
{
int i = 0;
for(std::list<Media>::iterator itr=Liste.begin();itr != Liste.end();itr++)
{
QPixmap pixmap(QString().fromStdString(itr->_PicUrl));
GraphicItem *item = new GraphicItem(pixmap);
Items.push_back(item);
m_GraphicsScene->addItem(item);
item->setPos(25+i,150);
i+=200;
}

SelectIndx = 0;
LoadMenuItems(SelectIndx);
Items[SelectIndx]->SelectedStatus(true);

}

void TestView::Animate()
{
for(int i = 0; i < Items.size(); ++i)
Items[i]->Animate();

bool stop = true;
for(int i = 0; i < Items.size(); ++i)
{
if(!Items.at(i)->IsRightPlace())
{
stop = false;
break;
}
}
if(stop)
timer->stop();
}


void TestView::LoadMenuItems(int Indx)
{
GetXYData(Indx);
for(int i = 0; i < Items.size(); ++i)
Items[i]->SetRightPlace(points[i].x(),points[i].y());

}

void TestView::GetXYData(int Indx)
{

points = new QPoint[Items.size()];

points[Indx].setX(225);
points[Indx].setY(150);

for(int i=Indx-1;i>=0;i--)
{
points[i].setX(points[i+1].x()-200);
points[i].setY(150);
}

for(int i=Indx+1;i<Items.size();i++)
{
points[i].setX(points[i-1].x()+200);
points[i].setY(150);
}
for(int i=0;i<Items.size();i++)
printf("%d = x=%d,y=%d*\n",i,points[i].x(),points[i].y());

}

wysota
30th September 2009, 11:44
I think we have a different understanding of the word "minimal". Please strip it to the absolute minimum (not more than 30 lines in total) and post it as an attachment.