[solved] Incorrect move of widget in graphicsview
-
I am experiencing weird behaviour when I move my own "DraggableLabel" widget with the mouse in a QGraphicsView.
The DraggableLabel widget is derived from QLabel to override mousePressEvent and mouseMoveEvent. I have wrapped the label in a QGraphicsProxyWidget by adding it to the scene with addWidget. The label is intended to show an image which can then be manipulated.The idea is to do some transformations on this widget like scale, rotate and move position. All of these operations seem to work nicely. I can drag the image about with the mouse and do the other transformations via some "dial" widgets on the main window.
So now the problem: After rotating the draggablelabel more than e.g. 20 degrees I see weird results when dragging the widget by mouse. At 180 degrees the weird effect is the biggest and the images goes off-screen almost immediately.
I am quite sure some coordinate translation fails or is translating from the wrong reference. My label has no parent. Is that a problem? And if yes, what should the parent be?
I have read the forums and studied the examples since this is my first QT project that uses a graphics view. Unfortunately I was not able to find anything similar to what I was doing and I am also unable to work out what mistake I have made. So I was hoping someone in here could help me.
This is the code I used:
MyMainWindow.h
@
#include "testqt.h"
#include <QGraphicsProxyWidget>
#include <QGraphicsRectItem>class DraggableLabel : public QLabel
{
Q_OBJECTpublic:
explicit DraggableLabel() : QLabel() {}protected:
void mousePressEvent(QMouseEvent *event) {
dragStart = event->pos();
}void mouseMoveEvent(QMouseEvent *event) { setGeometry(QRect(geometry().topLeft() + event->pos() - dragStart, rect().size())); }
private:
QPoint dragStart;};
class MyMainWindow: public TestQt
{
Q_OBJECTpublic:
MyMainWindow(QWidget *parent=0);
virtual ~MyMainWindow();void AddImage();
protected:
QGraphicsScene scene;
QGraphicsWidget* image;public slots:
void scaleImage( int num );
void rotateImage( int num );
void moveImageX( int num );
void moveImageY( int num );
};
@MyMainWindow.cpp
@
#include "MyMainWindow.h"
#include <QGraphicsGridLayout>
#include <QLabel>
#include <QTextEdit>
#include <QString>
#include <QPoint>
#include <QPainter>
#include <QMouseEvent>MyMainWindow::MyMainWindow(QWidget *parent)
:
TestQt(parent)
{
// TODO Auto-generated constructor stub}
MyMainWindow::~MyMainWindow() {
// TODO Auto-generated destructor stub
}void MyMainWindow::AddImage()
{
QImage* imageWidget = new QImage(":/trolltech/styles/commonstyle/images/standardbutton-help-32.png");
DraggableLabel * imageLabel = new DraggableLabel;imageLabel->setPixmap(QPixmap::fromImage(*imageWidget));
image = scene.addWidget(imageLabel);
image->setTransformOriginPoint(image->geometry().center());
ui.graphicsView->setScene(&scene);
bool ok = connect(ui.dial, SIGNAL(valueChanged(int)), this, SLOT(scaleImage(int))); ok = connect(ui.dial_2, SIGNAL(valueChanged(int)), this, SLOT(rotateImage(int))); ok = connect(ui.dial_3, SIGNAL(valueChanged(int)), this, SLOT(moveImageX(int))); ok = connect(ui.dial_4, SIGNAL(valueChanged(int)), this, SLOT(moveImageY(int)));
}
void MyMainWindow::scaleImage( int num )
{
image->setScale(static_cast<double>(num) / 10.0);
}void MyMainWindow::rotateImage( int num )
{
image->setRotation(static_cast<double>(num));
}void MyMainWindow::moveImageX( int num )
{
image->setPos(num, image->y());
}void MyMainWindow::moveImageY( int num )
{
image->setPos(image->x(), num);
}
@If you want I can zip the entire project to make reproducing easier. I don't (yet) know how to upload it here though.
Thanks in advance for your help,
Joost -
Cannot use a text item because I need an image. But I guess I can use a QGraphicsPixmapItem. Do not know why I did not see this one before... Anyways, the pixmap item seems to work as I expect, so problem solved!
(I am still curious though why the widget version fails though. Is this a bug in QT or did I do something wrong? Maybe later I want something more complex than a pixmap in the graphics view and then it will still fail...)
-
The problem is that the widget has its own event handling, and that interferes with the event handling of the graphics view framework. If you don't really, realy need it, I suggest you stay away from using QWidgets inside QGraphicsView. I view it as a failed experiment that is still in the API for to compatibility reasons.