qt旋转矩形后,鼠标拖动改变矩形依旧不变 具体例子
时间: 2023-08-06 11:23:30 浏览: 115
下面是一个基于Qt的例子,展示如何实现旋转矩形后,鼠标拖动改变矩形但依旧保持不变的效果。您可以根据自己的需求进行修改:
```C++
#include <QGraphicsView>
#include <QGraphicsScene>
#include <QGraphicsRectItem>
#include <QApplication>
#include <QMouseEvent>
#include <QPointF>
#include <cmath>
class RotatableRect : public QGraphicsRectItem
{
public:
RotatableRect(qreal x, qreal y, qreal w, qreal h): QGraphicsRectItem(x, y, w, h)
{
setFlag(QGraphicsItem::ItemIsMovable);
setFlag(QGraphicsItem::ItemSendsGeometryChanges);
setFlag(QGraphicsItem::ItemIsSelectable);
angle = 0.0;
center = rect().center();
}
enum { Type = UserType + 1 };
int type() const override { return Type; }
void mousePressEvent(QGraphicsSceneMouseEvent *event) override
{
if (event->button() == Qt::LeftButton)
{
prev_mouse_pos = event->scenePos();
prev_pos = pos();
}
QGraphicsRectItem::mousePressEvent(event);
}
void mouseMoveEvent(QGraphicsSceneMouseEvent *event) override
{
if (event->buttons() & Qt::LeftButton)
{
QPointF mouse_diff = event->scenePos() - prev_mouse_pos;
QPointF new_pos = prev_pos + mouse_diff;
// calculate new coordinates in rotated system
QPointF delta = new_pos - pos();
qreal dx = delta.x();
qreal dy = delta.y();
qreal cos_a = std::cos(-angle);
qreal sin_a = std::sin(-angle);
qreal x = cos_a * dx - sin_a * dy;
qreal y = sin_a * dx + cos_a * dy;
QPointF new_pos_rotated = pos() + QPointF(x, y);
// update item position
setPos(new_pos_rotated - center);
}
QGraphicsRectItem::mouseMoveEvent(event);
}
void mouseReleaseEvent(QGraphicsSceneMouseEvent *event) override
{
QGraphicsRectItem::mouseReleaseEvent(event);
}
QRectF boundingRect() const override
{
QRectF rect = QGraphicsRectItem::boundingRect();
qreal margin = 2.0;
return rect.adjusted(-margin, -margin, margin, margin);
}
void paint(QPainter *painter, const QStyleOptionGraphicsItem *option, QWidget *widget) override
{
painter->save();
painter->translate(center);
painter->rotate(angle);
painter->translate(-center);
QGraphicsRectItem::paint(painter, option, widget);
painter->restore();
}
QVariant itemChange(GraphicsItemChange change, const QVariant &value) override
{
if (change == QGraphicsItem::ItemPositionChange)
{
QPointF new_pos = value.toPointF();
// calculate new coordinates in rotated system
QPointF delta = new_pos - pos();
qreal dx = delta.x();
qreal dy = delta.y();
qreal cos_a = std::cos(angle);
qreal sin_a = std::sin(angle);
qreal x = cos_a * dx - sin_a * dy;
qreal y = sin_a * dx + cos_a * dy;
QPointF new_pos_rotated = pos() + QPointF(x, y);
// update item position
return new_pos_rotated - center;
}
else if (change == QGraphicsItem::ItemTransformChange)
{
angle = transform().rotateRadians(0.0, Qt::ZAxis);
center = rect().center();
}
return QGraphicsRectItem::itemChange(change, value);
}
private:
QPointF prev_mouse_pos;
QPointF prev_pos;
qreal angle;
QPointF center;
};
int main(int argc, char *argv[])
{
QApplication a(argc, argv);
QGraphicsScene scene;
QGraphicsView view(&scene);
view.setRenderHint(QPainter::Antialiasing);
view.setDragMode(QGraphicsView::RubberBandDrag);
RotatableRect *rect = new RotatableRect(-50, -50, 100, 100);
rect->setBrush(Qt::red);
scene.addItem(rect);
view.setSceneRect(-200, -200, 400, 400);
view.show();
return a.exec();
}
```
在这个例子中,我们继承了QGraphicsRectItem类,重载了鼠标事件和位置变化事件,并且在paint()函数中实现了旋转矩形的绘制。在鼠标事件中,我们使用了旋转矩形的中心点和角度,将鼠标移动的距离转化为相对于旋转后的坐标系的坐标偏移量,并根据新的坐标计算出旋转后的矩形位置和大小。
最后,我们创建了一个RotatableRect对象,并将其添加到QGraphicsScene中。通过QGraphicsView来显示场景,您可以通过鼠标进行拖动并改变矩形的大小和位置,而矩形旋转后,鼠标拖动改变矩形但依旧不变。
阅读全文