用qgraphicsitem实现一个可用用鼠标调整大小,方向和位置的矩形
时间: 2023-06-12 18:03:27 浏览: 128
在QGraphicsScene上画矩形
5星 · 资源好评率100%
可以继承QGraphicsItem类,实现自己的可调整大小、方向和位置的矩形类。具体步骤如下:
1. 定义矩形类,继承QGraphicsItem类,重写boundingRect()和paint()函数。
```
class ResizableRectItem : public QGraphicsItem {
public:
ResizableRectItem(QGraphicsItem *parent = nullptr);
QRectF boundingRect() const override;
void paint(QPainter *painter, const QStyleOptionGraphicsItem *option, QWidget *widget) override;
};
```
2. 实现boundingRect()函数,返回矩形的边界矩形。
```
QRectF ResizableRectItem::boundingRect() const {
return QRectF(-50, -50, 100, 100);
}
```
3. 实现paint()函数,绘制矩形和调整手柄。
```
void ResizableRectItem::paint(QPainter *painter, const QStyleOptionGraphicsItem *option, QWidget *widget) {
// 绘制矩形
painter->drawRect(-50, -50, 100, 100);
// 绘制调整手柄
painter->setBrush(Qt::white);
painter->drawEllipse(-55, -55, 10, 10);
painter->drawEllipse(45, -55, 10, 10);
painter->drawEllipse(-55, 45, 10, 10);
painter->drawEllipse(45, 45, 10, 10);
}
```
4. 实现鼠标事件函数,处理鼠标按下、移动和释放事件,实现矩形的调整。
```
void ResizableRectItem::mousePressEvent(QGraphicsSceneMouseEvent *event) {
if (event->button() == Qt::LeftButton) {
// 记录鼠标按下的位置
m_lastPos = event->pos();
}
}
void ResizableRectItem::mouseMoveEvent(QGraphicsSceneMouseEvent *event) {
// 计算鼠标移动的距离
QPointF delta = event->pos() - m_lastPos;
// 根据调整手柄的位置,调整矩形
if (event->buttons() & Qt::LeftButton) {
if (QRectF(-55, -55, 10, 10).contains(delta)) {
// 调整左上角
setPos(pos() + delta);
QRectF rect = boundingRect();
setRect(rect.x() + delta.x(), rect.y() + delta.y(), rect.width() - delta.x(), rect.height() - delta.y());
} else if (QRectF(45, -55, 10, 10).contains(delta)) {
// 调整右上角
setPos(pos() + QPointF(0, delta.y()));
QRectF rect = boundingRect();
setRect(rect.x(), rect.y() + delta.y(), rect.width() + delta.x(), rect.height() - delta.y());
} else if (QRectF(-55, 45, 10, 10).contains(delta)) {
// 调整左下角
setPos(pos() + QPointF(delta.x(), 0));
QRectF rect = boundingRect();
setRect(rect.x() + delta.x(), rect.y(), rect.width() - delta.x(), rect.height() + delta.y());
} else if (QRectF(45, 45, 10, 10).contains(delta)) {
// 调整右下角
QRectF rect = boundingRect();
setRect(rect.x(), rect.y(), rect.width() + delta.x(), rect.height() + delta.y());
} else {
// 移动矩形
setPos(pos() + delta);
}
// 更新鼠标位置
m_lastPos = event->pos();
}
}
void ResizableRectItem::mouseReleaseEvent(QGraphicsSceneMouseEvent *event) {
Q_UNUSED(event);
}
```
完整代码如下:
```
#include <QApplication>
#include <QGraphicsScene>
#include <QGraphicsView>
#include <QGraphicsItem>
#include <QPainter>
class ResizableRectItem : public QGraphicsItem {
public:
ResizableRectItem(QGraphicsItem *parent = nullptr);
QRectF boundingRect() const override;
void paint(QPainter *painter, const QStyleOptionGraphicsItem *option, QWidget *widget) override;
void mousePressEvent(QGraphicsSceneMouseEvent *event) override;
void mouseMoveEvent(QGraphicsSceneMouseEvent *event) override;
void mouseReleaseEvent(QGraphicsSceneMouseEvent *event) override;
private:
QPointF m_lastPos;
};
ResizableRectItem::ResizableRectItem(QGraphicsItem *parent)
: QGraphicsItem(parent)
{
setFlag(QGraphicsItem::ItemIsMovable, true);
setFlag(QGraphicsItem::ItemIsSelectable, true);
}
QRectF ResizableRectItem::boundingRect() const {
return QRectF(-50, -50, 100, 100);
}
void ResizableRectItem::paint(QPainter *painter, const QStyleOptionGraphicsItem *option, QWidget *widget) {
// 绘制矩形
painter->drawRect(-50, -50, 100, 100);
// 绘制调整手柄
painter->setBrush(Qt::white);
painter->drawEllipse(-55, -55, 10, 10);
painter->drawEllipse(45, -55, 10, 10);
painter->drawEllipse(-55, 45, 10, 10);
painter->drawEllipse(45, 45, 10, 10);
}
void ResizableRectItem::mousePressEvent(QGraphicsSceneMouseEvent *event) {
if (event->button() == Qt::LeftButton) {
// 记录鼠标按下的位置
m_lastPos = event->pos();
}
}
void ResizableRectItem::mouseMoveEvent(QGraphicsSceneMouseEvent *event) {
// 计算鼠标移动的距离
QPointF delta = event->pos() - m_lastPos;
// 根据调整手柄的位置,调整矩形
if (event->buttons() & Qt::LeftButton) {
if (QRectF(-55, -55, 10, 10).contains(delta)) {
// 调整左上角
setPos(pos() + delta);
QRectF rect = boundingRect();
setRect(rect.x() + delta.x(), rect.y() + delta.y(), rect.width() - delta.x(), rect.height() - delta.y());
} else if (QRectF(45, -55, 10, 10).contains(delta)) {
// 调整右上角
setPos(pos() + QPointF(0, delta.y()));
QRectF rect = boundingRect();
setRect(rect.x(), rect.y() + delta.y(), rect.width() + delta.x(), rect.height() - delta.y());
} else if (QRectF(-55, 45, 10, 10).contains(delta)) {
// 调整左下角
setPos(pos() + QPointF(delta.x(), 0));
QRectF rect = boundingRect();
setRect(rect.x() + delta.x(), rect.y(), rect.width() - delta.x(), rect.height() + delta.y());
} else if (QRectF(45, 45, 10, 10).contains(delta)) {
// 调整右下角
QRectF rect = boundingRect();
setRect(rect.x(), rect.y(), rect.width() + delta.x(), rect.height() + delta.y());
} else {
// 移动矩形
setPos(pos() + delta);
}
// 更新鼠标位置
m_lastPos = event->pos();
}
}
void ResizableRectItem::mouseReleaseEvent(QGraphicsSceneMouseEvent *event) {
Q_UNUSED(event);
}
int main(int argc, char *argv[]) {
QApplication a(argc, argv);
QGraphicsScene scene;
QGraphicsView view(&scene);
ResizableRectItem *rect = new ResizableRectItem;
scene.addItem(rect);
view.show();
return a.exec();
}
```
阅读全文