qtqgraphicsviewqgraphicssceneqlabelpixmap

QT QGraphicsScene with QLabel and QPixmap


I have a QGraphicsView, in that I have a QGraphicsScene, in that I have a QLabel and I set a .png picture as QPixmap into the QLabel. The .png is set in background.qrc resource file. My QLabel's size is 600x400. Without the pixmap it's okay, the QGraphicsScene's size is 600x400 too. But when I set the pixmap to the QLabel and scale it, it fails. The QLabel's size is the same, the pixmap is scaled well within the QLabel and only visible within it, but the QGraphicsScene adopts the real size of the QPixmap, which is 720x720. So the QLabel is visible with the QPixmap in it's correct size, but there is a gray place around it, since the scene is bigger. How can I fix this and make it work? I want the QGraphicScene to stay on the size of the QLabel.

Here's the code:

#include "mainwindow.h"
#include "ui_mainwindow.h"
#include <QPixmap>
#include <QGraphicsView>
#include <QGraphicsScene>
#include <QLabel>

MainWindow::MainWindow(QWidget *parent) :
    QMainWindow(parent),
    ui(new Ui::MainWindow)
{
    ui->setupUi(this);
    QGraphicsView *myView = new QGraphicsView(this);
    QGraphicsScene *myScene= new QGraphicsScene();
    QLabel *myLabel= new QLabel();
    myLabel->setBaseSize(QSize(600, 400));
    myLabel->resize(myLabel->baseSize());
    myLabel->setScaledContents(true);
    QPixmap pixmapBackground(":/new/cross.png");
    myLabel->setPixmap(pixmapBackground);
    myScene->addWidget(myLabel);
    myView->setScene(myScene);
    setCentralWidget(myView);
}

MainWindow::~MainWindow()
{
    delete ui;
}

Solution

  • From your example code, you don't set the scene's size. You can do this with a call to setSceneRect. As the documentation states, when the rect is not set: -

    If unset, or if set to a null QRectF, sceneRect() will return the largest bounding rect of all items on the scene since the scene was created (i.e., a rectangle that grows when items are added to or moved in the scene, but never shrinks).

    Therefore without setting the scene rect, when the label is added to the scene, its size is changing, as in this example

    #include <QApplication>
    #include <QGraphicsView>
    #include <QGraphicsScene>
    #include <QLabel>
    #include <QPixmap>
    
    int main(int argc, char *argv[])
    {
        QApplication a(argc, argv);
    
        QGraphicsView *myView = new QGraphicsView;
        QGraphicsScene *myScene= new QGraphicsScene();
    
        // constrain the QGraphicsScene size
        // without this, the defect as stated in the question is visible
        myScene->setSceneRect(0,0,600,400); 
    
        QLabel *myLabel= new QLabel;    
        myLabel->setBaseSize(QSize(600, 400));
        myLabel->resize(myLabel->baseSize());
        myLabel->setScaledContents(true);
    
        QPixmap pixmapBackground(720, 720);
        pixmapBackground.fill(QColor(0, 255, 0)); // green pixmap
    
        myLabel->setPixmap(pixmapBackground);
        myScene->addWidget(myLabel);
        myView->setScene(myScene);
        myView->show();
    
        return a.exec();
    }
    

    This should result in the correct scene size, as demonstrated here: -

    enter image description here

    As discussed in the comments, the example code above works as expected on OS X, but there still appears to be an issue when executing on Windows 10.