RottenRonin
RottenRonin

Reputation: 77

QGraphicsView shows nothing

I'm still learning Qt, I did a little project in Qt, i create a simple ui using qt ui designer, and using QGraphicsView to display a image loaded by QFileDialog, but when I added loaded image file to QgraphicsScene, the image is not displayed in the graphicview. The graphicView stay blank, please help me, thanks !

 Project2::Project2(QWidget *parent, Qt::WFlags flags)
: QMainWindow(parent, flags)
{
ui = new Ui::Project2Class;
ui->setupUi(this);

this->scene = new QGraphicsScene;

this->scene->setSceneRect(0, 0, 649, 459);

connect(ui->mapLoaderButton, SIGNAL(clicked()), this, SLOT(GetfilePath()));


ui->graphicsView->setScene(this->scene);    
}


 void Project2::GetfilePath()
   {

    QString filePath = QFileDialog::getOpenFileName(this, tr("Select file"), "", tr("Files (*.jpg*)"));

    if (filePath.isNull() == false)
    {
    QImage image(filePath);

    QSize size = image.size();
    ui->graphicsView->scene()->addItem(&QGraphicsPixmapItem(QPixmap::fromImage(image)));
    ui->graphicsView->scene()->update();
    ui->graphicsView->viewport()->update();
}}

Upvotes: 3

Views: 2120

Answers (1)

Jamin Grey
Jamin Grey

Reputation: 10487

QGraphicsScene, and most of Qt, takes ownership of the variable. The variable should be dynamically allocated.

Variables created on the stack won't work, because their lifetimes are too short and the QObject will later try and delete them.

You need to create your QGraphicsPixmapItem with 'new'.

ui->graphicsView->scene()->addItem(new QGraphicsPixmapItem(QPixmap::fromImage(image)));

Everything that inherits from QObject can own (and be owned by) other QObject classes. When a QObject is destroyed, it calls 'delete' on all its children. QObject classes want to 'own' their children. By 'own' I mean control the lifetimes of.

In your case, you were creating the QObject (QGraphicsPixmapItem) on the stack. It's lifetime is then controlled by the stack (but the QObject thinks it's controlling it), and the stack will delete it by the time it reaches the semi-colon of that 'addItem()' function-call.

As a general C++ rule-of-thumb, if a function is asking for a pointer, don't give it a temporary (unnamed) object. As a general Qt rule-of-thumb, if a function is asking for a pointer, don't even given it a named local-variable - most want a dynamically allocated variable, so look the function up on the documentation and see if it mentions 'taking ownership'. If so, 'new' it and let Qt later 'delete' it.

Upvotes: 3

Related Questions