I have a QGraphicsView in a QDockWidget, in which I'm displaying a PNG image. If I create a QPixMapItem in the dockwidget's constructor, and call a dockwidget's member function (a public slot) from within the constructor to display the image, it works fine.
However, if I invoke the slot from my MainWindow (a class called 'IView') via a signal, then the image does not show. What am I doing wrong?
Dockwidget construcor:
IvConfDockWidget::IvConfDockWidget(IView *parent) :
QDockWidget(parent),
ui(new Ui::IvConfDockWidget)
{
ui->setupUi(this);
MyGraphicsView *zoomGraphicsView = new MyGraphicsView();
MyGraphicsScene *zoomScene = new MyGraphicsScene();
ui->zoomLayout->addWidget(zoomGraphicsView);
QPixmap zoomPixmap = QPixmap("/home/mischa/logo.png");
QGraphicsPixmapItem *zoomPixmapItem = new QGraphicsPixmapItem(zoomPixmap);
updateZoomWindowReceived(zoomPixmapItem); // does not work if called from MainWindow
}
Here is the public slot:
void IvConfDockWidget::updateZoomWindowReceived(QGraphicsPixmapItem *zoomPixmapItem)
{
zoomGraphicsView->resetMatrix();
zoomScene->clear();
zoomScene->addItem(zoomPixmapItem);
zoomGraphicsView->setScene(zoomScene);
zoomGraphicsView->show();
}
If I comment out updateZoomWindowReceived()
in the constructor, and call it via a signal from my MainWindow, then the graphics does not show. Here is the code in my MainWindow:
IvConfDockWidget *icdw = new IvConfDockWidget;
connect(this, &IView::updateZoomWindow, icdw, &IvConfDockWidget::updateZoomWindowReceived);
QPixmap zoomPixmap = QPixmap("/home/mischa/logo.png");
icdw->zoomGraphicsView->resetMatrix();
QGraphicsPixmapItem *newItem = new QGraphicsPixmapItem(zoomPixmap);
emit updateZoomWindow(newItem);
And for completeness, my derived versions of QGraphicsView and QGraphicsScene:
#define MYGRAPHICSVIEW_H
#include <QGraphicsView>
#include <QDebug>
#include <QMouseEvent>
#include <QScrollBar>
class MyGraphicsView : public QGraphicsView
{
Q_OBJECT
private:
QPointF rightDragStartPos;
QPointF rightDragCurrentPos;
QPointF rightDragEndPos;
QPointF leftDragStartPos;
QPointF leftDragCurrentPos;
QPointF leftDragEndPos; // unused
QPointF middleDragStartPos;
QPointF middleDragCurrentPos;
QPointF middleDragEndPos;
bool rightButtonPressed = false;
bool leftButtonPressed = false;
bool middleButtonPressed = false;
QPoint previousMousePoint;
bool _pan = false;
int _panStartX = 0;
int _panStartY = 0;
public:
explicit MyGraphicsView();
void mouseMoveEvent(QMouseEvent *event);
void mousePressEvent(QMouseEvent *event);
void mouseReleaseEvent(QMouseEvent *event);
QScrollBar *sxbar = nullptr;
QScrollBar *sybar = nullptr;
QString middleMouseMode = "DragMode";
int x = 0;
int y = 0;
signals:
void currentMousePos(QPointF);
void rightDragTravelled(QPointF);
void middleDragTravelled(QPointF pointStart, QPointF pointEnd);
void middleWCSTravelled(QPointF pointStart, QPointF pointEnd);
void middleWCSreleased();
void leftDragTravelled(QPointF pointStart, QPointF pointEnd);
void rightPress();
void leftPress(QPointF pointStart);
void middlePress(QPointF point);
void leftButtonReleased();
void rightButtonReleased();
void middleButtonReleased();
void middlePressResetCRPIX();
public slots:
void updateMiddleMouseMode(QString mode);
};
#endif // MYGRAPHICSVIEW_H
and
#ifndef MYGRAPHICSSCENE_H
#define MYGRAPHICSSCENE_H
#include <QObject>
#include <QGraphicsScene>
#include <QKeyEvent>
class MyGraphicsScene : public QGraphicsScene
{
Q_OBJECT
public:
MyGraphicsScene();
signals:
void itemDeleted();
protected:
void keyReleaseEvent(QKeyEvent * keyEvent);
};
#endif // MYGRAPHICSSCENE_H
I figured it out. My MainWindow uses a hybrid drive/RAM data model which can be in different states, and it happened that in one of the states the signal was never emitted. Once I fixed that, the behavior is as desired.
Sorry for the noise.