Ich habe Probleme mit der Objektrotation um das Objekt-Center nach der Verwendung der vordefinierten Option in Qt bewegen. Ich erstelle ein QGraphicsRectItem und setze das ItemIsMovable Attribut. Die Rotationen funktionieren gut (Shift mit der linken Maustaste klicken und ziehen Sie den Gegenstand).Drehen Sie QGraphicsItem mit ItemIsMovable Attribut nach dem Verschieben
Jetzt bewegen Sie das Rechteck, (Shift linke Maustaste) und versuchen Sie es erneut zu drehen. Die Drehung ist falsch. Ich berechne die Mitte des Rechtecks mit dem sceneBoundingBox(). Normalize.center(). Wenn ich diesen Punkt nach dem Zug zeichne, ist er am richtigen Ort.
Ich habe versucht sowohl setOriginTransform und mit der QTransform-Methode. Beide geben mir die gleichen Ergebnisse.
Bin ich verwirrt über die Koordinatensysteme der Szene im Vergleich zum Rotationskoordinatensystem? Wie ändert sich das nach dem Umzug?
Hier ist eine abgespeckte kompilierbare Header-Datei und Quellcode, der das Problem demonstriert. Ich benutze Qt 5.7 auf einem Mac. Die Rotationen werden in der Funktion rotateItem (...) berechnet. Alle Koordinaten sollten im Szenen-Koordinatensystem liegen.
#include <cmath>
#include <QApplication>
#include <QWidget>
#include <QGraphicsView>
#include <QGraphicsScene>
#include <QBrush>
#include <QPen>
#include <QGraphicsSceneMouseEvent>
#include "myrect.h"
// THIS IS THE PROBLEM FUNCTION
// calculate rotations about the center of a given shape item.
void rotateItem(QAbstractGraphicsShapeItem* shape, QPointF center,
QPointF moved, QPointF initial_pos)
{
// get the angle from the center to the initial click point
qreal init_x = initial_pos.x() - center.x();
qreal init_y = initial_pos.y() - center.y();
qreal initial_angle = std::atan2(init_y, init_x);
qreal x = moved.x() - center.x();
qreal y = moved.y() - center.y();
qreal mv_angle = std::atan2(y,x);
// get the changed angle
qreal angle = (mv_angle - initial_angle)*180/M_PI;
if (std::fabs(angle) > 360.0)
angle = 0.0;
// both transforms give the same result
QTransform xform;
xform.translate(center.x(), center.y());
xform.rotate(angle);
xform.translate(-center.x(), -center.y());
shape->setTransform(xform, false);
//shape->setTransformOriginPoint(center);
//shape->setRotation(angle);
}
MyRect::MyRect(qreal x, qreal y, qreal width, qreal height) :
QGraphicsRectItem(x, y, width, height)
{
mInitialPos.setX(0.0);
mInitialPos.setY(0.0);
mInitialCenter.setX(0.0);
mInitialCenter.setY(0.0);
}
void MyRect::mousePressEvent(QGraphicsSceneMouseEvent *event)
{
if (event->button() == Qt::LeftButton)
{
//if (event->modifiers() == Qt::ControlModifier)
if (event->modifiers() == Qt::ShiftModifier)
{
// ALL COORDINATES ARE IN THE SCENE COORDINATE FRAME (is that a problem?)
mInitialPos = event->scenePos();
mInitialCenter = this->sceneBoundingRect().normalized().center();
}
else
QAbstractGraphicsShapeItem::mousePressEvent(event);
}
}
void MyRect::mouseMoveEvent(QGraphicsSceneMouseEvent *event)
{
if (event->buttons() == Qt::LeftButton)
{
if (event->modifiers() == Qt::ShiftModifier)
{
// Call the rotation function
rotateItem(this, mInitialCenter, event->scenePos(), mInitialPos);
event->accept();
}
else
{
QAbstractGraphicsShapeItem::mouseMoveEvent(event);
}
}
}
void MyRect::mouseReleaseEvent(QGraphicsSceneMouseEvent* event)
{
QAbstractGraphicsShapeItem::mouseReleaseEvent(event);
}
QGraphicsItem* add_rectangle(QGraphicsScene* scene)
{
MyRect* rectangle = new MyRect(-50, 10, 80, 80);
QBrush red_brush(Qt::red);
QPen pen(Qt::black);
pen.setWidth(4);
rectangle->setBrush(red_brush);
rectangle->setPen(pen);
rectangle->setFlag(QGraphicsItem::ItemIsMovable);
scene->addItem(rectangle);
return rectangle;
}
int main(int argc, char *argv[])
{
QApplication a(argc, argv);
QWidget w;
QGraphicsView* graphicsView = new QGraphicsView(&w);
graphicsView->setGeometry(0,0,500,500);
QGraphicsScene* scene = new QGraphicsScene(&w);
graphicsView->setScene(scene);
add_rectangle(scene);
w.show();
return a.exec();
}
Hier ist die Objekt-Header-Datei abgespeckte #ifndef MYRECT_H #define MYRECT_H #include #include
class MyRect : public QObject, public QGraphicsRectItem
{
Q_OBJECT
public:
MyRect(qreal x, qreal y, qreal width, qreal height);
void mousePressEvent(QGraphicsSceneMouseEvent* event);
void mouseMoveEvent(QGraphicsSceneMouseEvent* event);
void mouseReleaseEvent(QGraphicsSceneMouseEvent* event);
private:
QPointF mInitialPos;
QPointF mInitialCenter;
};
#endif // MYRECT_H