Qt에서 미리 정의 된 이동 옵션을 사용한 후 객체 중심에 대한 객체 회전에 문제가 있습니다. QGraphicsRectItem을 만들고 ItemIsMovable 특성을 설정합니다. 회전은 잘 작동합니다 (마우스 왼쪽 버튼으로 클릭하고 항목 위로 드래그).QGraphicsItem을 ItemIsMovable 속성으로 이동 후 이동
이제 사각형을 이동 (마우스 왼쪽 버튼으로 끌기)하고 다시 회전 해보십시오. 회전이 잘못되었습니다. sceneBoundingBox(). normalize.center()를 사용하여 사각형의 중심을 계산합니다. 이동 후에 그 점을 그려 보면 올바른 위치에 있습니다.
저는 setOriginTransform과 QTransform 메서드를 모두 사용했습니다. 그들은 둘 다 저에게 동일한 결과를줍니다.
장면의 좌표계와 회전 좌표계에 대해 혼란스러워합니까? 이사 한 후에 어떻게 바뀌나요?
여기에는 문제를 보여주는 컴파일 가능한 헤더 파일과 소스 코드가 있습니다. Qt 5.7을 Mac에서 사용하고 있습니다. 회전은 rotateItem (...) 함수에서 계산됩니다. 모든 좌표는 장면 좌표계에 있어야합니다. 여기
#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();
}
는 벗었 오브젝트 헤더 파일 #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