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

avatar
作者
猴君
阅读量:0

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 "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 "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); 

广告一刻

为您即时展示最新活动产品广告消息,让您随时掌握产品活动新动态!