PDA

View Full Version : Custum QGraphicsItem not call the paint method



Nosba
27th February 2016, 11:39
Hi all,

I have a custom QGraphicsItem:


header:


#ifndef MERCATOR_GRAPHICS_ITEM_H
#define MERCATOR_GRAPHICS_ITEM_H
#include <QPainter>
#include <QGraphicsItem>
#include <QDebug>
#include <QSize>

class Mercator_graphics_item : public QGraphicsItem
{
public:
Mercator_graphics_item(QSize size_of_view);

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

void resize(QSize new_size);
QSize get_dimension();

private:
QSize * size_of_Item;
};

#endif // MERCATOR_GRAPHICS_ITEM_H



.cpp file:


#include "mercator_graphics_item.h"

Mercator_graphics_item::Mercator_graphics_item(QSi ze size_of_view)
{
size_of_Item = new QSize(size_of_view.width(),size_of_view.height());
qDebug() << boundingRect();

}

QRectF Mercator_graphics_item::boundingRect() const
{
return QRectF(0,0,100,100);
}

void Mercator_graphics_item::paint(QPainter *painter, const QStyleOptionGraphicsItem *option, QWidget *widget)
{
qDebug() << "paint called";
Q_UNUSED(option);
Q_UNUSED(widget);
QRectF map = boundingRect();



painter->drawRect(map);

}

void Mercator_graphics_item::resize(QSize new_size)
{
*size_of_Item = new_size;
update();
}

QSize Mercator_graphics_item::get_dimension()
{
return *this->size_of_Item;
}


and this is the method where I create my item:


ui->setupUi(this);
draw_scene = new QGraphicsScene(this);
Mercator_graphics_item map(ui->graphicsView->size());

qDebug() << &map;

draw_scene->addItem(&map);
draw_scene->update();
ui->graphicsView->setScene(draw_scene);


draw_scene is declared in a different file and it is of type QGraphicsScene *. The problem is that when I run my application nothing is drawn on the graphicsView, and the paint method is not called, I know because the string "print called" (line 17 of .cpp file) is never printed on my console..

Can someone explain me what I'm doing wrong please?

I used the same procedure on another project and in it works well...

anda_skoa
27th February 2016, 11:56
ui->setupUi(this) looks like this is code in the constructor of a widget.

"map" is allocated on the stack, it will be deleted once the constructor ends.
When the widget and the graphics view inside it are painted, there is no item anymore.

Cheers,
_

Nosba
27th February 2016, 12:12
I tried to move my code on a private slot that is called when a button is pressed:



void Students_Navigation::on_pushButton_clicked()
{
qDebug() << ui->graphicsView->size();
Mercator_graphics_item map(ui->graphicsView->size());

qDebug() << &map;

ui->graphicsView->update();

draw_scene->addItem(&map);
draw_scene->update();
ui->graphicsView->setScene(draw_scene);

}


but it doesn't work yet. when I press the button the qDebug() lines are displayed but only the lines that are in that method not the lines of the paint method...
So the paint method is not called..

anda_skoa
27th February 2016, 13:08
I tried to move my code on a private slot that is called when a button is pressed:

How would that help?



So the paint method is not called..
The item is still destroyed right away.

Cheers,
_

Nosba
27th February 2016, 14:46
I finally realized.




qDebug() << ui->graphicsView->size();

this->map = new Mercator_graphics_item(ui->graphicsView->size());

qDebug() << map;

ui->graphicsView->update();

draw_scene->addItem(map);
draw_scene->update();
ui->graphicsView->setScene(draw_scene);



the pointer map is declared in the header file...

Using the new operand I allocate the map object in the Heap so it is not destroyed at the and of the slot's stack.

Am I right or it works only by chance?

anda_skoa
27th February 2016, 14:51
Am I right or it works only by chance?
Yes, you are right.

The problem was the really short life time of the item due to stack allocation.

Cheers,
_

Nosba
27th February 2016, 15:15
Thank you very much.

Added after 4 minutes:

A last question by new user... how can I mark this thread like [SOLVED]?