通过QGraphicsItem绘制可拖拽,改变大小的矩形

#pragma once

#include <QGraphicsItem>
#include <QPointF>
#include <QColor>
class PointGraphicsItem: public QGraphicsItem
{
	public:
		PointGraphicsItem(QGraphicsItem* parent = Q_NULLPTR);
		~PointGraphicsItem() override;
	
		QRectF boundingRect() const override;
	protected:

		void paint(QPainter* painter, const QStyleOptionGraphicsItem* option, QWidget* widget) override;
	private:
		QColor m_paint_color;
		const double Width = 10.0;
		const double Height = 10.0;
};



#include "PointGraphicsItem.h"
#include <QDebug>
#include <QPainter>
#include <QGraphicsSceneMouseEvent>
PointGraphicsItem::PointGraphicsItem(QGraphicsItem* parent)
	: QGraphicsItem(parent)
{
	setFlag(QGraphicsItem::ItemIsFocusable);
	setFlag(QGraphicsItem::ItemIsMovable);
	setAcceptDrops(true);
}

PointGraphicsItem::~PointGraphicsItem() = default;

QRectF PointGraphicsItem::boundingRect() const
{
	return { pos().x() - Width / 2.0, pos().y() - Height / 2.0, Width, Height };
}

void PointGraphicsItem::paint(QPainter * painter, const QStyleOptionGraphicsItem * option, QWidget * widget)
{
	//painter->save();
	//m_paint_color = Qt::yellow;
	//painter->setBrush(m_paint_color);
	//const QRectF rect(pos().x() - Width / 2.0, pos().y() - Height / 2.0, Width, Height);
	//painter->drawRect(rect);
	//painter->restore();
}
#pragma once

#include <QGraphicsItem>
#include <QtWidgets/QApplication>

class PointGraphicsItem;
class RectangleGraphicsItem : public QGraphicsItem
{
	enum class DragType
	{
		//没有进行拖拽
		Release,

		//五个点的定义
		LeftTop,
		RightTop,
		LeftBottom,
		RightBottom,
		Center,
	};
public:
	RectangleGraphicsItem(QGraphicsItem* parent = nullptr);
	~RectangleGraphicsItem() override = default;

	QRectF boundingRect() const override;
	void paint(QPainter* painter, const QStyleOptionGraphicsItem* option, QWidget* widget) override;

protected:
	void mousePressEvent(QGraphicsSceneMouseEvent* event) override;
	void mouseMoveEvent(QGraphicsSceneMouseEvent* event) override;
	void mouseReleaseEvent(QGraphicsSceneMouseEvent* event) override;

	void hoverEnterEvent(QGraphicsSceneHoverEvent* event) override;
	void hoverLeaveEvent(QGraphicsSceneHoverEvent* event) override;
private:
		//拖动点
	QSharedPointer<PointGraphicsItem> m_left_top_item;
	QSharedPointer<PointGraphicsItem> m_left_bottom_item;
	QSharedPointer<PointGraphicsItem> m_right_top_item;
	QSharedPointer<PointGraphicsItem> m_right_bottom_item;
	QSharedPointer<PointGraphicsItem> m_center_item;
	//拖动起始位置
	QPointF m_startPos;
	//当前拖拽的点
	DragType m_drag_type;
	//画笔颜色
	QColor m_line_color;
};


#include "RectangleGraphicsItem.h"

#include <QGraphicsScene>
#include <QPainter>
#include <QDebug>
#include <QGraphicsSceneMouseEvent>
#include "GlobalConfig.h"
#include "PointGraphicsItem.h"
RectangleGraphicsItem::RectangleGraphicsItem(QGraphicsItem* parent)
	: QGraphicsItem(parent),
	m_left_top_item(new PointGraphicsItem),
	m_left_bottom_item(new PointGraphicsItem),
	m_right_top_item(new PointGraphicsItem),
	m_right_bottom_item(new PointGraphicsItem),
	m_center_item(new PointGraphicsItem),
	m_drag_type(DragType::Release)
{
	setFlag(QGraphicsItem::ItemIsFocusable);
	setFlag(QGraphicsItem::ItemIsMovable);
	setAcceptDrops(true);
	setAcceptHoverEvents(true);

	m_line_color = Qt::blue;

	m_left_top_item->setPos({ 10.0,10.0 });
	m_left_bottom_item->setPos({ 10.0,210.0 });
	m_right_top_item->setPos({ 210.0,10.0 });
	m_right_bottom_item->setPos({ 210.0,210.0 });
	m_center_item->setPos({ 110,110 });
	qDebug() << "left top,     x:" << m_left_top_item->pos().x() << " y:" << m_left_top_item->pos().y();
	qDebug() << "left bottom,  x:" << m_left_bottom_item->pos().x() << " y:" << m_left_bottom_item->pos().y();
	qDebug() << "right top,    x:" << m_right_top_item->pos().x() << " y:" << m_right_top_item->pos().y();
	qDebug() << "right bottom, x:" << m_right_bottom_item->pos().x() << " y:" << m_right_bottom_item->pos().y();
	qDebug() << "--------------------------------------------------------------------------------------------";
}

QRectF RectangleGraphicsItem::boundingRect() const
{
	const QPointF point(20.0, 20.0);
	const QPointF startPoint(m_left_top_item->pos());
	const QPointF endPoint(m_right_bottom_item->pos() + point);
	qDebug() << "boundingRect, location:" << endPoint - startPoint;
	return { startPoint, endPoint };
}

void RectangleGraphicsItem::paint(QPainter* painter, const QStyleOptionGraphicsItem* option, QWidget* widget)
{
	painter->save();

	painter->setPen(QPen(m_line_color));
	painter->setBrush(m_line_color);
	const QLineF line1(m_left_top_item->boundingRect().x() + 5, m_left_top_item->boundingRect().y() + 5,
		m_right_top_item->boundingRect().x() + 5, m_right_top_item->boundingRect().y() + 5);
	painter->drawLine(line1);

	const QLineF line2(m_left_top_item->boundingRect().x() + 5, m_left_top_item->boundingRect().y() + 5,
		m_left_bottom_item->boundingRect().x() + 5, m_left_bottom_item->boundingRect().y() + 5);
	painter->drawLine(line2);

	const QLineF line3(m_left_bottom_item->boundingRect().x() + 5, m_left_bottom_item->boundingRect().y() + 5,
		m_right_bottom_item->boundingRect().x() + 5, m_right_bottom_item->boundingRect().y() + 5);
	painter->drawLine(line3);

	const QLineF line4(m_right_bottom_item->boundingRect().x() + 5, m_right_bottom_item->boundingRect().y() + 5,
		m_right_top_item->boundingRect().x() + 5, m_right_top_item->boundingRect().y() + 5.0);
	painter->drawLine(line4);
	painter->restore();

	painter->save();
	painter->setPen(QPen(Qt::black));
	painter->setBrush(Qt::yellow);
	painter->drawRect(m_left_top_item->boundingRect());
	painter->drawRect(m_left_bottom_item->boundingRect());
	painter->drawRect(m_right_top_item->boundingRect());
	painter->drawRect(m_right_bottom_item->boundingRect());
	painter->restore();

	painter->save();
	painter->setPen(QPen(Qt::black));
	painter->setBrush(Qt::red);
	painter->drawRect(m_center_item->boundingRect());
	painter->restore();

	painter->save();
	painter->setPen(QPen(Qt::black));
	const qreal width = m_right_bottom_item->pos().x() - m_left_bottom_item->pos().x() + 10;
	const qreal height = m_right_bottom_item->pos().y() - m_right_top_item->pos().y() + 10;

	const QPointF textPos(m_left_bottom_item->pos().x(), m_left_bottom_item->y() + 20);
	painter->drawText(textPos, QStringLiteral("宽度:%1,高度:%2").arg(width).arg(height));
	painter->restore();
}

void RectangleGraphicsItem::mousePressEvent(QGraphicsSceneMouseEvent* event)
{
	if (event->button() == Qt::LeftButton)
	{
		m_startPos = event->pos();//鼠标左击时,获取当前鼠标在图片中的坐标,
		qDebug() << "pressed pos  x:" << m_startPos.x() << "   y:" << m_startPos.y();
		if (m_left_top_item->boundingRect().contains(m_startPos))
		{
			setCursor(Qt::PointingHandCursor);
			m_drag_type = DragType::LeftTop;
		}
		else if (m_left_bottom_item->boundingRect().contains(m_startPos))
		{
			setCursor(Qt::PointingHandCursor);
			m_drag_type = DragType::LeftBottom;
		}
		else if (m_right_top_item->boundingRect().contains(m_startPos))
		{
			setCursor(Qt::PointingHandCursor);
			m_drag_type = DragType::RightTop;
		}
		else if (m_right_bottom_item->boundingRect().contains(m_startPos))
		{
			setCursor(Qt::PointingHandCursor);
			m_drag_type = DragType::RightBottom;
		}
		else if (m_center_item->boundingRect().contains(m_startPos))
		{
			setCursor(Qt::PointingHandCursor);
			m_drag_type = DragType::Center;
		}
	}
}

void RectangleGraphicsItem::mouseMoveEvent(QGraphicsSceneMouseEvent* event)
{
	const QPointF point = (event->pos() - m_startPos);

	switch (m_drag_type)
	{
	case DragType::Release:
		break;
	case DragType::LeftTop:
	{
		m_left_top_item->moveBy(point.x(), point.y());
		m_left_bottom_item->moveBy(point.x(), 0);
		m_right_top_item->moveBy(0, point.y());
		m_right_bottom_item->moveBy(0, 0);
		m_center_item->moveBy(point.x() / 2.0, point.y() / 2.0);
		//增加限制条件
		break;
	}

	case DragType::RightTop:
	{
		m_left_top_item->moveBy(0, point.y());
		m_left_bottom_item->moveBy(0, 0);
		m_right_top_item->moveBy(point.x(), point.y());
		m_right_bottom_item->moveBy(point.x(), 0);
		m_center_item->moveBy(point.x() / 2.0, point.y() / 2.0);
		break;
	}

	case DragType::LeftBottom:
	{
		m_left_top_item->moveBy(point.x(), 0);
		m_left_bottom_item->moveBy(point.x(), point.y());
		m_right_top_item->moveBy(0, 0);
		m_right_bottom_item->moveBy(0, point.y());
		m_center_item->moveBy(point.x() / 2.0, point.y() / 2.0);
		break;
	}

	case DragType::RightBottom:
	{
		m_left_top_item->moveBy(0, 0);
		m_left_bottom_item->moveBy(0, point.y());
		m_right_top_item->moveBy(point.x(), 0);
		m_right_bottom_item->moveBy(point.x(), point.y());
		m_center_item->moveBy(point.x() / 2.0, point.y() / 2.0);
		break;
	}
	case DragType::Center:
	{
		m_left_top_item->moveBy(point.x(), point.y());
		m_left_bottom_item->moveBy(point.x(), point.y());
		m_right_top_item->moveBy(point.x(), point.y());
		m_right_bottom_item->moveBy(point.x(), point.y());
		m_center_item->moveBy(point.x(), point.y());
		break;
	}
	}
	qDebug() << "left top,     x:" << m_left_top_item->pos().x() << " y:" << m_left_top_item->pos().y();
	qDebug() << "left bottom,  x:" << m_left_bottom_item->pos().x() << " y:" << m_left_bottom_item->pos().y();
	qDebug() << "right top,    x:" << m_right_top_item->pos().x() << " y:" << m_right_top_item->pos().y();
	qDebug() << "right bottom, x:" << m_right_bottom_item->pos().x() << " y:" << m_right_bottom_item->pos().y();
	qDebug() << "--------------------------------------------------------------------------------------------";
	m_startPos = event->pos();
	scene()->update();
}

void RectangleGraphicsItem::mouseReleaseEvent(QGraphicsSceneMouseEvent* event)
{
	setCursor(Qt::CrossCursor);
	m_drag_type = DragType::Release;
	//m_line_color = Qt::blue;
}

void RectangleGraphicsItem::hoverEnterEvent(QGraphicsSceneHoverEvent* event)
{
	m_line_color = Qt::yellow;
	qDebug() << "hoverEnterEvent";
}

void RectangleGraphicsItem::hoverLeaveEvent(QGraphicsSceneHoverEvent* event)
{
	m_line_color = Qt::blue;
	qDebug() << "hoverLeaveEvent";
}
  • 3
    点赞
  • 19
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
可以通过自定义一个继承自QGraphicsItem的类来实现绘制可移动的同心圆弧。具体实现步骤如下: 1. 在类中添加需要的成员变量,例如圆心坐标、半径、起始角度、结束角度等。 2. 重写boundingRect()函数和paint()函数,boundingRect()函数用于返回图形项的边界矩形,paint()函数用于绘制图形项。在paint()函数中,可以使用QPainter来绘制同心圆弧。 3. 重写mousePressEvent()、mouseMoveEvent()和mouseReleaseEvent()函数,实现鼠标拖动图形项的功能。在mousePressEvent()函数中,记录下鼠标点击时的坐标;在mouseMoveEvent()函数中,计算鼠标移动的距离,更新图形项的位置;在mouseReleaseEvent()函数中,将鼠标点击时的坐标清空。 下面是一个简单的实现示例: ``` #include <QPainter> #include <QGraphicsItem> #include <QStyleOptionGraphicsItem> class ArcItem : public QGraphicsItem { public: ArcItem(qreal x, qreal y, qreal radius, qreal startAngle, qreal endAngle, QGraphicsItem *parent = nullptr) : QGraphicsItem(parent), m_x(x), m_y(y), m_radius(radius), m_startAngle(startAngle), m_endAngle(endAngle) { setFlag(ItemIsMovable); } QRectF boundingRect() const override { return QRectF(m_x - m_radius, m_y - m_radius, m_radius * 2, m_radius * 2); } void paint(QPainter *painter, const QStyleOptionGraphicsItem *option, QWidget *widget) override { painter->setRenderHint(QPainter::Antialiasing); QRectF rect(m_x - m_radius, m_y - m_radius, m_radius * 2, m_radius * 2); painter->drawArc(rect, m_startAngle * 16, (m_endAngle - m_startAngle) * 16); } protected: void mousePressEvent(QGraphicsSceneMouseEvent *event) override { m_lastPos = event->pos(); } void mouseMoveEvent(QGraphicsSceneMouseEvent *event) override { QPointF delta = event->pos() - m_lastPos; m_x += delta.x(); m_y += delta.y(); m_lastPos = event->pos(); update(); } void mouseReleaseEvent(QGraphicsSceneMouseEvent *event) override { m_lastPos = QPointF(); } private: qreal m_x; qreal m_y; qreal m_radius; qreal m_startAngle; qreal m_endAngle; QPointF m_lastPos; }; ``` 使用示例: ``` // 创建场景和视图 QGraphicsScene scene; QGraphicsView view(&scene); // 创建同心圆弧图形项并添加到场景中 ArcItem *item = new ArcItem(100, 100, 50, 30, 150); scene.addItem(item); // 显示视图 view.show(); ```

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

qingchuu

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值