0
votes

I have created an override of QGraphicsView for displaying images inside a QMdiSubWindow in my application. Later I plan to add support for other floating shapes on top of that so a QLabel just wasn't enough. Here's the basic layout of the class:

class ImageView : public QGraphicsView
{
public:
    ImageView(QWidget *parent);
    ~ImageView();

    bool clean() const
    {
        return _clean;
    }

    void showImage(const QString &path);

private:
    virtual void resizeEvent(QResizeEvent *event);

    bool _clean;
    QGraphicsScene *_scene;
    QPixmap _viewPixmap;
    QGraphicsPixmapItem *_viewPixmapItem;
};

I want to avoid allocating a QPixmap element every time I load a new image, so I just keep one in the class, and also create a pixmap graphics item in the constructor like this:

ImageView::ImageView(QWidget *parent) : QGraphicsView(parent), _clean(true)
{
    _scene = new QGraphicsScene(this); 
    _scene->setBackgroundBrush(Qt::lightGray);
    _viewPixmapItem = _scene->addPixmap(_viewPixmap);
    setScene(_scene);
}

Later when someone clicks on an image in the app, I call (from the main gui class) the showImage function:

void ImageView::showImage(const QString &path)
{
    _clean = false;
    _viewPixmap.load(path);
    _viewPixmapItem->setPixmap(_viewPixmap);
}

My problem is that the first time I use showImage(), the image is not placed at the top left corner in the view, but rather somewhere near the middle, with most of it outside the view and yet no scrollbar is visible. The next time I try to show an image, I get a resize event after the call to showImage(), the image is displayed correctly, and all subsequent displays are okay; the image is aligned with the top-left corner of the view, and scrollbars are visible to reflect that the image is too large for the view (I plan to add zoom capability later). I read the docs over and over but just got more confused, can you please give me a hint of what I am missing? Thanks.

EDIT: Here's how the image looks at the first call to showImage, and here is how it looks on the subsequent ones, which is what I want. You can see that the image view widget is placed in a MDI-style sub window within a QMdiArea.

EDIT2: The application writes information to a log file, here's the part where I try to show the first three images:

Activated image in project list, name: obiekt_blisko-0000_0.bmp
ViewMdiSubWindow::prefit: Pre-fitting, new size: 516x352
MDI window size: 516x352
Child QWidget window size: 628x477
ImageView::resizeEvent: Received resize event, old size was: -1x-1, new size: 500x313
ImageView::showImage: Showing image: D:\praca\dane\pomiar3d_3\obiekt_blisko_L\obiekt_blisko-0000_0.bmp
View size after setting new pixmap: 502x315
Item position (parent coords): 0,0

(After this, the image is displayed incorrectly)

Activated image in project list, name: obiekt_blisko-0001_0.bmp
MDI window size: 516x352
Child QWidget window size: 502x315
ImageView::showImage: Showing image: D:\praca\dane\pomiar3d_3\obiekt_blisko_L\obiekt_blisko-0001_0.bmp
View size after setting new pixmap: 502x315
Item position (parent coords): 0,0
ImageView::resizeEvent: Received resize event, old size was: 500x313, new size: 483x296

(Now the image is OK)

Activated image in project list, name: obiekt_blisko-0002_0.bmp
MDI window size: 516x352
Child QWidget window size: 502x315
ImageView::showImage: Showing image: D:\praca\dane\pomiar3d_3\obiekt_blisko_L\obiekt_blisko-0002_0.bmp
View size after setting new pixmap: 502x315
Item position (parent coords): 0,0

(This and the next events are identical and the images are OK)

2

2 Answers

3
votes

The reason the image is showing with its top-left corner at the center of the view is because your scene has a sceneRect of (0,0,0,0) and QGraphicsView shows the scene centered by default.

Set seneRect to a fix rect will probably solve your problem. Calling centerOn after the image change will also help.

0
votes

Wouldn't _viewPixmapItem->setPos(0, 0) work in showImage? As you describe it, it's just in the wrong postion. Maybe centered with the initial zero size.