Qt鼠标拖动绘制基本几何图形
概述
用Qt鼠標(biāo)事件實(shí)現(xiàn)基本幾何圖形的繪制,支持直線、矩形、圓形、橢圓。后期可以在此基礎(chǔ)上進(jìn)行擴(kuò)展。
效果圖
實(shí)現(xiàn)
本示例使用QGraphics體系來實(shí)現(xiàn),因?yàn)橐苿?dòng)對(duì)象,所以生成的圖形必須是一個(gè)單獨(dú)的對(duì)象,鼠標(biāo)拖動(dòng)繪制的過程是在臨時(shí)層中完成,release后生成一個(gè)矢量的圖形item并添加到場景中。
關(guān)鍵代碼
主場景中有一個(gè)父rootItem,在scene中將鼠標(biāo)或觸控事件傳到rooitem后動(dòng)態(tài)繪制臨時(shí)的圖形,release事件后生成一個(gè)標(biāo)準(zhǔn)的圖形對(duì)象:
void GsRootItem::drawPress(int id, const QPointF &p) {ShapeInfo info;info.firstPos = p;info.type = getCurType();m_Objs.insert(id,info); }void GsRootItem::drawMove(int id, const QPointF &lastPoint, const QPointF &curPoint) {if(!m_Objs.contains(id)){return;}ShapeInfo info = m_Objs.value(id);m_pTempLayer->drawShape(info.type,info.firstPos,curPoint); }void GsRootItem::drawRelease(int id, const QPointF &point) {if(!m_Objs.contains(id)){return;}ShapeInfo info = m_Objs.value(id);drawRealShape(info.type,info.firstPos,point);m_Objs.remove(id);m_pTempLayer->clear(); }... void GsRootItem::drawRealShape(GsShapeType type, QPointF p1, QPointF p2) {//計(jì)算圖形繪制區(qū)域QRectF rect;rect.setX(qMin(p1.x(),p2.x()));rect.setY(qMin(p1.y(),p2.y()));if(type == Shape_Circle){rect.setWidth(qAbs(p1.y() - p2.y()));rect.setHeight(qAbs(p1.y() - p2.y()));}else{rect.setWidth(qAbs(p1.x() - p2.x()));rect.setHeight(qAbs(p1.y() - p2.y()));}rect.adjust(-5,-5,5,5);GsShapeBaseItem * item = m_pShapeFactory->getShapeItem(type,rect,this);item->drawShape(p1,p2); }drawRealShape函數(shù)就是用與創(chuàng)建一個(gè)獨(dú)立的幾何圖形,通過以下的工廠模式來生成
GsShapeBaseItem * item = m_pShapeFactory->getShapeItem(type,rect,this);工廠代碼:
GsShapeBaseItem *GsShapeFactory::getShapeItem(GsShapeType type,QRectF rectF,QGraphicsObject *parent) {GsShapeBaseItem * item = nullptr;switch (type) {case Shape_Line:item = new GsShapeLineItem(rectF,parent);break;case Shape_Rectange:item = new GsShapeRectangeItem(rectF,parent);break;case Shape_Circle:item = new GsShapeCircleItem(rectF,parent);break;case Shape_Oval:item = new GsShapeOvalItem(rectF,parent);break;default:break;}item->setZValue(10);return item; }在工廠類中會(huì)創(chuàng)建不同的圖形對(duì)象。每一個(gè)圖形對(duì)象是繼承于QGraphicsObject然后重寫paint函數(shù)去進(jìn)行繪制,比如說原型:
void GsShapeCircleItem::paint(QPainter *painter, const QStyleOptionGraphicsItem *option, QWidget *widget) {painter->setRenderHint(QPainter::Antialiasing);QColor color = Qt::red;//(rand()%255,rand()%255,rand()%255);painter->setBrush(color);if(m_bTap){painter->setPen(QPen(Qt::yellow,5,Qt::SolidLine,Qt::RoundCap,Qt::RoundJoin));}else{painter->setPen(QPen(color,3,Qt::SolidLine,Qt::RoundCap,Qt::RoundJoin));}painter->drawEllipse(m_firstPoint.x(),m_firstPoint.y(),qAbs(m_lastPoint.y() - m_firstPoint.y()),qAbs(m_lastPoint.y() - m_firstPoint.y())); }其他圖形類似。
實(shí)現(xiàn)圖形的選擇和拖動(dòng),需要在item中添加以下兩句:
setFlag(ItemIsSelectable,true); setFlag(ItemIsMovable,true);然后就可以自由拖動(dòng)啦。
代碼太多, 就不全部列出來了,基本邏輯都很簡單。
代碼下載地址
github下載
與50位技術(shù)專家面對(duì)面20年技術(shù)見證,附贈(zèng)技術(shù)全景圖總結(jié)
以上是生活随笔為你收集整理的Qt鼠标拖动绘制基本几何图形的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: git 常用别名设置
- 下一篇: Qt Remote Object(QtR