QGraphicsView with QGraphicsPixmapItem that resizes on resize of QGraphicsView
Hey Guys,
I subclassed QGraphicsView and an QGraphicsPixmapItem...
What i want: I want to add a Pixmap to the GraphicsView and resize it (if the pixmap does not have it's desired maximum size) on resizing the GraphicsView..
What i receive: an unhandled exception in QPaintDevice::paintingActive()
Code:
{ return painters != 0; } // seems i get the exception here
Code:
BackgroundItem
::BackgroundItem(const QPixmap &pixmap
){
myOriginalPixmap = pixmap;
}
QPixmap BackgroundItem
::getOriginalPixmap(){ return myOriginalPixmap;
}
Code:
void FloorPlanGraphicsView::init()
{
//scene->setSceneRect(0,0,this->geometry().width(),this->geometry().height();
setScene(canvas);
}
void FloorPlanGraphicsView
::setFloorPlan(const QPixmap &image
){ BackgroundItem *backImg = new BackgroundItem(image);//.scaled(geometry().width(),geometry().height(),Qt::KeepAspectRatio));
scene()->addItem(backImg);
backImg->setPos(0,0);
backImg->setZValue(0);
backImg->setPixmap(image.scaled(geometry().width(),geometry().height(),Qt::KeepAspectRatio));
}
void FloorPlanGraphicsView
::resizeEvent(QResizeEvent *event
){ scene()->setSceneRect(0,0,this->geometry().width(),this->geometry().height());
QList<QGraphicsItem*> graphicItems = scene()->items();
for (int i = 0; i < graphicItems.size(); ++i){
if (graphicItems.at(i)->type() == FloorPlanGraphicsView::BackgroundType){
BackgroundItem *myBackItem = qgraphicsitem_cast<BackgroundItem*>(graphicItems.at(i));
if(this->geometry().width() <= myBackItem->getOriginalPixmap().size().width() && this->geometry().height() <= myBackItem->getOriginalPixmap().size().height())
// i get the error immediately here on resize!
myBackItem->setPixmap(myBackItem->getOriginalPixmap().scaled(this->geometry().width(),this->geometry().height(),Qt::KeepAspectRatio));
else
myBackItem->setPixmap(myBackItem->getOriginalPixmap());
}
}
}
The invocation to setFloorPlan() looks like the following:
Code:
ui.
floorPlan->setFloorPlan
(QPixmap::fromImage(QImage::fromData(query.
value(0).
toByteArray())));
Do i have to reimplement a paint() function or something similar here?
Anbody any idea for me?
Re: QGraphicsView with QGraphicsPixmapItem that resizes on resize of QGraphicsView
Has really nobody an idea for me? =/
Re: QGraphicsView with QGraphicsPixmapItem that resizes on resize of QGraphicsView
Maybe the following is your problem.
From the docs (link):
Quote:
T qgraphicsitem_cast ( QGraphicsItem * item )
Returns the given item cast to type T if item is of type T; otherwise, 0 is returned.
Note: To make this function work correctly with custom items, reimplement the type() function for each custom QGraphicsItem subclass.
Check out the diagramscene and elasticnodes examples.
In backgrounditem.h add:
Code:
enum { Type = UserType +1 };
int type() const { return Type; }
And in FloorPlanGraphicsView::resizeEvent() change:
Code:
//if (graphicItems.at(i)->type() == FloorPlanGraphicsView::BackgroundType){
if (graphicItems.at(i)->type() == BackgroundItem::Type{
Re: QGraphicsView with QGraphicsPixmapItem that resizes on resize of QGraphicsView
Ney norobro!
Thanks for your reply, i have not posted that part of code cauze i thought it might not be useful for a reader - but i am aware of that ..
Here is the code from the header:
Code:
{
Q_OBJECT
public:
FloorPlanGraphicsView
(QWidget * parent
= 0);
~FloorPlanGraphicsView();
void setFloorPlan
(const QPixmap & image
);
void setIndicator
(const QImage & image
);
protected:
virtual void mouseDoubleClickEvent
(QMouseEvent *event
);
private:
void init();
void placeIndicator
(const QPointF & point
);
void removeIndicator
(const QPointF & point
);
};
{
public:
int type() const { return FloorPlanGraphicsView::IndicatorType; }
protected:
private:
};
{
public:
BackgroundItem
(const QPixmap &pixmap
);
virtual int type() const { return FloorPlanGraphicsView::BackgroundType; }
private:
};
Re: QGraphicsView with QGraphicsPixmapItem that resizes on resize of QGraphicsView
I don't think qgraphicsitem_cast will work the way you are using it.
Check your pointer in debug mode:
Code:
BackgroundItem *myBackItem = qgraphicsitem_cast<BackgroundItem*>(graphicItems.at(i));
Q_ASSERT(myBackItem);
Try static_cast instead.
Re: QGraphicsView with QGraphicsPixmapItem that resizes on resize of QGraphicsView
I changed the stuff a little bit and got another error facing the same problem as it seems ... as found out that the qgraphicsitem_cast isn't working i wanted to reply here -> then i saw your reply ;)
Anyways .. you're absolutely right.. and static_cast works as i want it to work... (in my new case - i will reconstruct the old one with the old files from SVN)
Could you give me an explanation why "qgraphicsitem_cast" is not working as i expected? Is that my fault or what's wrong here?
Re: QGraphicsView with QGraphicsPixmapItem that resizes on resize of QGraphicsView
I'm not sure what the advantage of qgraphicsitem_cast is. Maybe someone can enlighten us.
Anyway, here's the source code for qgraphicsitem_cast from qgraphicsitem.h:
Code:
template <class T>
inline T qgraphicsitem_cast
(QGraphicsItem *item
) {
|| (item && int(static_cast<T>(0)->Type) == item->type()) ? static_cast<T>(item) : 0;
}
Since you don't have "Type" defined in your BackgroundItem class, int(static_cast<BackgroundItem *>(0)->Type) returns 7 which is the parent Type (QGraphicsPixmapItem).
Thus:
The first part of the return statement above becomes: 7==1 which is false;
The conditional operator expression (true && 7 == 65538) is false;
Therefore zero is returned and you end up with a null pointer.
Hope this makes sense.
Re: QGraphicsView with QGraphicsPixmapItem that resizes on resize of QGraphicsView
Hmm what you said makes sense but i do NOT get the sense of that graphicsitem_cast .. looks complete senseless ...
Code:
template <class T>
inline T qgraphicsitem_cast
(QGraphicsItem *item
) {
|| (item && int(static_cast<T>(0)->Type) == item->type()) ? static_cast<T>(item) : 0;
}
I do not really get that part: "int(static_cast<T>(0)->Type) == item->type()"
What should that comparison be useful for?