使用QGraphicsView三件套绘制图片,绘制鼠标事件

Qt通过鼠标绘制线条、矩形、多边形本质都是根据鼠标的坐标位移,使用QPainter的自带的函数进行绘制。
QGraphicsView三件套事件传递机制:
具体代码开箱即用:
view.h

#include <QObject>
#include <QGraphicsView>
#include <QVector>
class GSELTestGraphicsScence;
class GSELTestGraphicsView  : public QGraphicsView
{
	Q_OBJECT
	
	Q_PROPERTY(QRect viewRect MEMBER m_viewRect READ GetRect WRITE SetRect NOTIFY viewRectChanged)

public:
	explicit GSELTestGraphicsView(QWidget *parent = Q_NULLPTR);
	~GSELTestGraphicsView() override;

protected:
	//void paintEvent(QPaintEvent* event) override;
	void mousePressEvent(QMouseEvent* event) override;
	void mouseMoveEvent(QMouseEvent* event) override;
	void mouseReleaseEvent(QMouseEvent* event) override;
	void wheelEvent(QWheelEvent* event) override;

signals:
	void viewRectChanged(QRect rect);
public:
	void OnInitView();
	void OnUnInitView();
	void SetRect(QRect rect);
	QRect GetRect()const;
private:
	QRect m_viewRect;
};

view.cpp

GSELTestGraphicsView::GSELTestGraphicsView(QWidget *parent)
	: QGraphicsView(parent)
{
	OnInitView();
}

GSELTestGraphicsView::~GSELTestGraphicsView()
{
	OnUnInitView();
}

void GSELTestGraphicsView::mousePressEvent(QMouseEvent* event)
{
	qDebug() << "GraphicsView: mousePressEvent " << event->pos();
    if (event->buttons() & Qt::LeftButton)
    {
        //m_point_pos.emplace_back(event->pos());
    }
    QGraphicsView::mousePressEvent(event);
}

void GSELTestGraphicsView::mouseMoveEvent(QMouseEvent* event)
{
   // qDebug() << "GraphicsView: mouseMoveEvent " << event->pos();
    QGraphicsView::mouseMoveEvent(event);
}

void GSELTestGraphicsView::mouseReleaseEvent(QMouseEvent* event)
{
    qDebug() << "GraphicsView: mouseReleaseEvent " << event->pos();
    this->update();
    QGraphicsView::mouseReleaseEvent(event);
}

void GSELTestGraphicsView::wheelEvent(QWheelEvent* event)
{
    QGraphicsView::wheelEvent(event);
}

void GSELTestGraphicsView::OnInitView()
{

}

void GSELTestGraphicsView::OnUnInitView()
{
	
}

void GSELTestGraphicsView::SetRect(QRect rect)
{
	m_viewRect = rect;
	emit viewRectChanged(rect);
}

QRect GSELTestGraphicsView::GetRect() const
{
	return m_viewRect;
}

Sence.h


#include <QGraphicsScene>
class GSELTestGraphicsScence : public QGraphicsScene
{
	Q_OBJECT

public:
	explicit GSELTestGraphicsScence(QObject *parent = Q_NULLPTR);
	~GSELTestGraphicsScence()override;
public:
    void OnInitSence();
    void OnUnInitSence();
protected:

    void mousePressEvent(QGraphicsSceneMouseEvent* event)override;
    void mouseMoveEvent(QGraphicsSceneMouseEvent* event)override;
    void mouseReleaseEvent(QGraphicsSceneMouseEvent* event)override;
    void wheelEvent(QGraphicsSceneWheelEvent* event)override;
signals:
    
private:

};

Sence.h

#include <QPainter>
#include <QGraphicsSceneMouseEvent>
#include <QDebug>
GSELTestGraphicsScence::GSELTestGraphicsScence(QObject*parent)
	: QGraphicsScene(parent)
{
	OnInitSence();
	
}

GSELTestGraphicsScence::~GSELTestGraphicsScence()
{
	OnUnInitSence();
}

void GSELTestGraphicsScence::OnInitSence()
{
	clearFocus();
}

void GSELTestGraphicsScence::OnUnInitSence()
{
	
}


void GSELTestGraphicsScence::mousePressEvent(QGraphicsSceneMouseEvent* event)
{
	qDebug() << "GraphicsScence: mousePressEvent " << event->pos();
	
	QGraphicsScene::mousePressEvent(event);
}

void GSELTestGraphicsScence::mouseMoveEvent(QGraphicsSceneMouseEvent* event)
{
	//qDebug() << "GraphicsScence: mouseMoveEvent " << event->pos();
	QGraphicsScene::mouseMoveEvent(event);
}

void GSELTestGraphicsScence::mouseReleaseEvent(QGraphicsSceneMouseEvent* event)
{
	qDebug() << "GraphicsScence: mouseReleaseEvent " << event->pos();
	QGraphicsScene::mouseReleaseEvent(event);
}

void GSELTestGraphicsScence::wheelEvent(QGraphicsSceneWheelEvent* event)
{
	QGraphicsScene::wheelEvent(event);
}

Item.h

#include <QGraphicsItem>
#include <QPainter>
#include <QVector>
#include <array>
#include <QPointF>
#include <QPixmap>
#include "GSDrawShap.h"
class GSELTestGraphicsItem  : public QObject, public QGraphicsItem
{
	Q_OBJECT
	Q_INTERFACES(QGraphicsItem)
public:
	explicit GSELTestGraphicsItem(QObject* parent = nullptr);
	~GSELTestGraphicsItem() override;
public:
	void OnInitItem();
	void OnUnInitItem();
protected:
	QRectF boundingRect() const override;
	void paint(QPainter* painter, const QStyleOptionGraphicsItem* option, QWidget* widget = Q_NULLPTR)override;
	void mousePressEvent(QGraphicsSceneMouseEvent* event) override;
	void mouseMoveEvent(QGraphicsSceneMouseEvent* event) override;
	void mouseReleaseEvent(QGraphicsSceneMouseEvent* event) override;
	void wheelEvent(QGraphicsSceneWheelEvent* event) override;
public slots:

private:
	GSDraw::DrawType m_draw_type;
	GSDrawShap* m_draw_shap;
	GSDrawShap* m_draw_img_shap;
	QVector<QPointF> m_point_pos;
	QPointF m_start_pos;
	QPointF m_end_pos;
};

Item.h

#include "GSELTestGraphicsItem.h"
#include "GSELTestCommon.h"
#include <QGraphicsSceneMouseEvent>
#include <QDebug>
#include <QScreen>
#include <QGuiApplication>
#include <QCursor>  

GSELTestGraphicsItem::GSELTestGraphicsItem(QObject* parent):QObject(parent), QGraphicsItem()
{
	setFlag(QGraphicsItem::ItemIsFocusable);
	//setFlag(QGraphicsItem::ItemIsMovable);
	setFlag(QGraphicsItem::ItemIsSelectable);
	this->setAcceptHoverEvents(true);

	m_draw_shap =new GSDrawShap(nullptr);
	m_draw_img_shap = new GSDrawShap(nullptr);
	m_draw_img_shap->SetDrawType(GSDraw::DrawType::image);

	m_draw_type = GSDraw::DrawType::rect;
	m_draw_shap->SetDrawType(m_draw_type);	
}

GSELTestGraphicsItem::~GSELTestGraphicsItem()
{

}

void GSELTestGraphicsItem::OnInitItem()
{

}

void GSELTestGraphicsItem::OnUnInitItem()
{

}

QRectF GSELTestGraphicsItem::boundingRect() const
{
	QScreen* screen = QGuiApplication::primaryScreen();
	int viewWidth = screen->geometry().width() / 2;
	int viewHeight = screen->geometry().height();
	return QRectF(0, 0, viewWidth, viewHeight);
}

void GSELTestGraphicsItem::paint(QPainter* painter, const QStyleOptionGraphicsItem* option, QWidget* widget)
{
	m_draw_img_shap->paint(*painter);
	m_draw_shap->paint(*painter);
}


void GSELTestGraphicsItem::mousePressEvent(QGraphicsSceneMouseEvent* event)
{
	qDebug() << "GSELTestGraphicsItem: mousePressEvent " << event->pos();
	setFocus();
	//setCursor(Qt::ClosedHandCursor);

	//this->boundingRect().contains(event->pos())  

	if (event->button() & Qt::LeftButton)
	{
		if (m_draw_type == GSDraw::DrawType::rect)
		{
			QPointF startPos = event->pos();
			QPointF endPos = event->pos();
			m_draw_shap->SetStartPos(startPos);
			m_draw_shap->SetEndPos(endPos);
		}
		else if (m_draw_type == GSDraw::DrawType::point)
		{
			QPointF startPos = event->pos();
			QPointF endPos = event->pos();
			m_draw_shap->SetStartPos(startPos);
			m_draw_shap->SetEndPos(endPos);
		}
	}
	
	QGraphicsItem::mousePressEvent(event);
}

void GSELTestGraphicsItem::mouseMoveEvent(QGraphicsSceneMouseEvent* event)
{	
	if (m_draw_type == GSDraw::DrawType::rect)
	{
		QPointF endPos = event->pos();
		m_draw_shap->SetEndPos(endPos);
		update(QRectF(m_start_pos, m_end_pos));			
	}	
	QGraphicsItem::mouseMoveEvent(event);
}

void GSELTestGraphicsItem::mouseReleaseEvent(QGraphicsSceneMouseEvent* event)
{
	qDebug() << "GSELTestGraphicsItem: mouseReleaseEvent " << event->pos();
	
	if (event->button() & Qt::LeftButton)
	{
		if (m_draw_type == GSDraw::DrawType::rect)
		{
		}
		else if (m_draw_type == GSDraw::DrawType::point)
		{
			QPointF endPos = event->pos();
			m_draw_shap->SetEndPos(endPos);
			update(endPos.x() - 5, endPos.y(), 10, 1);
			update(endPos.x(), endPos.y() - 5, 1, 10);
		}
	}
	QGraphicsItem::mouseReleaseEvent(event);
}


void GSELTestGraphicsItem::wheelEvent(QGraphicsSceneWheelEvent* event)
{
	QGraphicsItem::wheelEvent(event);
}

绘制事件用到的类
GSDraw、GSDrawImage、GSDrawPoints、GSDrawRectangle、GSDrawShap

#include <QObject>
#include <QPainter>
#include <QPoint>
#include <QPointF>
class GSDraw  : public QObject
{
	Q_OBJECT

public:
	GSDraw(QObject *parent);
	~GSDraw();
public:
	enum class DrawType {rect=0,point,line,image};
public:
	void SetPainter(QPainter, DrawType);
	void SetStartPos(QPoint&);
	void SetStartPos(QPointF&);
	void SetEndPos(QPoint&);
	void SetEndPos(QPointF&);
	void ClearPoints();
	virtual void paint(QPainter& painter);
protected:
	DrawType m_draw_type;
	QPoint m_start_pos;
	QPoint m_end_pos;
	QPointF m_start_pos_f;
	QPointF m_end_pos_f;
	QVector<QPoint> pointList;
	QVector<QPointF> pointfList;	
};

#include "GSDraw.h"

GSDraw::GSDraw(QObject *parent)
	: QObject(parent)
{}

GSDraw::~GSDraw()
{}

void GSDraw::SetPainter(QPainter painter, DrawType type)
{
	m_draw_type = type;
}

void GSDraw::SetStartPos(QPoint& pos)
{
	m_start_pos = pos;
	
}

void GSDraw::SetStartPos(QPointF& pos)
{
	m_start_pos_f = pos;
	pointfList.push_back(pos);
}

void GSDraw::SetEndPos(QPoint& pos)
{
	m_end_pos = pos;
}

void GSDraw::SetEndPos(QPointF& pos)
{
	m_end_pos_f = pos;
	pointfList.push_back(pos);
}

void GSDraw::ClearPoints()
{
	pointfList.clear();
}

void GSDraw::paint(QPainter& painter)
{

}
#include <QObject>
#include "GSDraw.h"

class GSDrawPoints  : public GSDraw
{
	Q_OBJECT

public:
	GSDrawPoints(QObject *parent = nullptr);
	~GSDrawPoints();
public:
	void paint(QPainter& painter) override;
};

#include "GSDrawPoints.h"

GSDrawPoints::GSDrawPoints(QObject *parent)
	: GSDraw(parent)
{}

GSDrawPoints::~GSDrawPoints()
{}

void GSDrawPoints::paint(QPainter & painter)
{
	painter.save();
	QPen pen;
	pen.setWidth(3);
	pen.setColor(QColor(255, 0, 0));
	painter.setPen(pen);

	for (auto point : pointfList)
	{
		painter.drawLine(point.x() - 5, point.y(), point.x() + 5, point.y());
		painter.drawLine(point.x(), point.y() + 5, point.x(), point.y() - 5);			
	}
	painter.restore();
}

#include <QObject>
#include "GSDraw.h"
class GSDrawRectangle  : public GSDraw
{
	Q_OBJECT

public:
	GSDrawRectangle(QObject *parent = nullptr);
	~GSDrawRectangle();
public:
	void paint(QPainter& painter) override;
};

#include "GSDrawRectangle.h"
#include <QRectF>
GSDrawRectangle::GSDrawRectangle(QObject *parent)
	: GSDraw(parent)
{}

GSDrawRectangle::~GSDrawRectangle()
{}

void GSDrawRectangle::paint(QPainter & painter)
{
	painter.save();
	QPen pen;
	pen.setWidth(3);
	pen.setColor(QColor(255, 0, 0));
	painter.setPen(pen);
	painter.drawRect(QRectF(m_start_pos_f, m_end_pos_f));
	painter.restore();
}
#include <QObject>
#include "GSDraw.h"

class GSDrawImage  : public GSDraw
{
	Q_OBJECT

public:
	GSDrawImage(QObject *parent = nullptr);
	~GSDrawImage();
public:
	void paint(QPainter& painter) override;
};

#include "GSDrawImage.h"
#include <QScreen>
#include <QGuiApplication>
GSDrawImage::GSDrawImage(QObject *parent)
	: GSDraw(parent)
{}

GSDrawImage::~GSDrawImage()
{}

void GSDrawImage::paint(QPainter & painter)
{
	QPixmap pix;
	pix.load(":/image/img1.jpg");
	int imgW = 480;
	int imgH = 640;
	QScreen* screen = QGuiApplication::primaryScreen();
	int viewWidth = screen->geometry().width() / 2;
	int viewHeight = screen->geometry().height();
	int leftTopX = (viewWidth - imgW) / 2;
	int leftTopY = (viewHeight - imgH) / 2;
	painter.drawPixmap(QRect(leftTopX, leftTopY, imgW, imgH), pix);
}

#include <QObject>
#include <QPainter>
#include "GSDraw.h"
class GSDrawShap  : public QObject
{
	Q_OBJECT

public:
	GSDrawShap(QObject *parent);
	~GSDrawShap();
public:
	void SetDrawType(GSDraw::DrawType);
	void SetPainter(QPainter, GSDraw::DrawType);
	void SetStartPos(QPoint&);
	void SetStartPos(QPointF&);
	void SetEndPos(QPoint&);
	void SetEndPos(QPointF&);
	void paint(QPainter& painter);
	void ClearPoints();
private:
	GSDraw* m_draw_obj;
	GSDraw::DrawType m_draw_type;
};

#include "GSDrawShap.h"
#include "GSDrawImage.h"
#include "GSDrawPoints.h"
#include "GSDrawRectangle.h"
GSDrawShap::GSDrawShap(QObject *parent)
	: QObject(parent)
{}

GSDrawShap::~GSDrawShap()
{}

void GSDrawShap::SetDrawType(GSDraw::DrawType type)
{
	m_draw_type = type;
	switch (type)
	{
	case GSDraw::DrawType::line:
		
		break;
	case GSDraw::DrawType::rect:
		m_draw_obj = new GSDrawRectangle();
		break;
	case GSDraw::DrawType::point:
		m_draw_obj = new GSDrawPoints();
		break;
	case GSDraw::DrawType::image:
		m_draw_obj = new GSDrawImage();
		break;
	default:
		break;
	}
}

void GSDrawShap::SetPainter(QPainter, GSDraw::DrawType)
{

}

void GSDrawShap::SetStartPos(QPoint& pos)
{
	m_draw_obj->SetStartPos(pos);
}

void GSDrawShap::SetStartPos(QPointF& pos)
{
	m_draw_obj->SetStartPos(pos);
}

void GSDrawShap::SetEndPos(QPoint& pos)
{
	m_draw_obj->SetEndPos(pos);
}

void GSDrawShap::SetEndPos(QPointF& pos)
{
	m_draw_obj->SetEndPos(pos);
}

void GSDrawShap::paint(QPainter& painter)
{
	m_draw_obj->paint(painter);
}

void GSDrawShap::ClearPoints()
{
	m_draw_obj->ClearPoints();
}

具体的使用方法

    QScreen* screen = QGuiApplication::primaryScreen();
    int viewWidth = screen->geometry().width() / 2;
    int viewHeight = screen->geometry().height();

    m_elScence = new GSELTestGraphicsScence();
    m_elScence->setSceneRect(QRect(0, 0, viewWidth - 2, viewHeight - 2));

    GSELTestGraphicsItem* item = new GSELTestGraphicsItem();
    //item->setFlag(QGraphicsItem::ItemIgnoresTransformations);//设置放大view,不影响item的大小,但是item的位置改变了
    m_elScence->addItem(item);
    m_elImgView = new GSELTestGraphicsView();

    ui->horizontalLayout_2->addWidget(m_elImgView);
    m_elImgView->setFixedSize(QSize(viewWidth, viewHeight));
    m_elImgView->setProperty("viewRect", QVariant::fromValue(QRect(0, 0, viewWidth, viewHeight)));
    m_elImgView->setScene(m_elScence);
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值