Qt實現(xiàn)繪制一個簡單多邊形的示例代碼
1. 概述
可以通過QT的重繪事件和鼠標事件來繪制多邊形,最簡單的辦法就是在繼承QWidget的窗體中重寫paintEvent、mousePressEvent等事件處理函數(shù)。QT提供了圖形繪制接口QPainter,通過該接口可以繪制多種圖形,包括多邊形。
2. 實現(xiàn)
2.1 代碼
新建一個基于QWidget的QT界面類GraphicsPainter,將其放置到想要顯示的窗體中。該類的具體代碼:
GraphicsPainter.h:
#ifndef GRAPHICSPAINTER_H #define GRAPHICSPAINTER_H #include <QWidget> class GraphicsPainter : public QWidget { Q_OBJECT public: explicit GraphicsPainter(QWidget *parent = nullptr); void SetDraw(bool bDraw); signals: void singalDrawOver(); public slots: protected: void paintEvent(QPaintEvent *); //繪制 void mousePressEvent(QMouseEvent *e); //按下 void mouseMoveEvent(QMouseEvent *e); //移動 void mouseReleaseEvent(QMouseEvent *e); //松開 void mouseDoubleClickEvent(QMouseEvent *event); //雙擊 bool bDraw; //是否處于繪制狀態(tài) bool bLeftClick; //是否已經(jīng)開始左鍵點擊,同時標識是否開始進行繪制 bool bMove; //是否處于繪制時的鼠標移動狀態(tài) QVector<QPointF> pointList; QPointF movePoint; }; #endif // GRAPHICSPAINTER_H
GraphicsPainter.cpp:
#include "graphicspainter.h" #include <QPainter> #include <QMouseEvent> #include <QDebug> GraphicsPainter::GraphicsPainter(QWidget *parent) : QWidget(parent) { //填充背景色 setAutoFillBackground(true); setBackgroundRole(QPalette::Base); bDraw = false; bLeftClick = false; bMove = false; setMouseTracking(true); } void GraphicsPainter::SetDraw(bool bDraw) { this->bDraw = bDraw; pointList.clear(); } //重新實現(xiàn)paintEvent void GraphicsPainter::paintEvent(QPaintEvent *) { QPainter painter(this); if(bDraw) { painter.setPen(QColor(255,0,0)); QVector<QLineF> lines; for(int i = 0; i<pointList.size()-1; i++) { QLineF line(QPointF(pointList[i].x(), pointList[i].y()), QPointF(pointList[i+1].x(), pointList[i+1].y())); lines.push_back(line); } if(bMove&&pointList.size()>0) { QLineF line(QPointF(pointList[pointList.size()-1].x(), pointList[pointList.size()-1].y()), movePoint); lines.push_back(line); } painter.drawLines(lines); } } //按下 void GraphicsPainter::mousePressEvent(QMouseEvent *e) { if(bDraw) { if(!bLeftClick) { pointList.clear(); bLeftClick = true; } } //qDebug()<<"Press"; } //移動 void GraphicsPainter::mouseMoveEvent(QMouseEvent *e) { if(bDraw&&bLeftClick) { movePoint = e->pos(); bMove = true; this->update(); } //qDebug()<<"Move"; } //松開 void GraphicsPainter::mouseReleaseEvent(QMouseEvent *e) { if(bDraw&&bLeftClick) { pointList.push_back(QPointF(e->x(), e->y())); bMove = false; this->update(); } //qDebug()<<"Release"; } //雙擊 void GraphicsPainter::mouseDoubleClickEvent(QMouseEvent *event) { if(bDraw) { bLeftClick = false; pointList.push_back(pointList[0]); this->update(); singalDrawOver(); } //qDebug()<<"DoubleClick"; }
2.2 解析
在重新實現(xiàn)的重繪事件中,通過QPainter繪制了一系列線組成線串,最后會首尾相連形成多邊形。這里的bMove標識是否處于繪制時的鼠標移動狀態(tài),只有鼠標左鍵點擊后才會確定為真正的節(jié)點:
//重新實現(xiàn)paintEvent void GraphicsPainter::paintEvent(QPaintEvent *) { QPainter painter(this); if(bDraw) { painter.setPen(QColor(255,0,0)); QVector<QLineF> lines; for(int i = 0; i<pointList.size()-1; i++) { QLineF line(QPointF(pointList[i].x(), pointList[i].y()), QPointF(pointList[i+1].x(), pointList[i+1].y())); lines.push_back(line); } if(bMove&&pointList.size()>0) { QLineF line(QPointF(pointList[pointList.size()-1].x(), pointList[pointList.size()-1].y()), movePoint); lines.push_back(line); } painter.drawLines(lines); } }
鼠標按下事件中,主要是通過bLeftClick值來確定是否已經(jīng)處于左鍵點擊狀態(tài),同時還能標識是否開始進行繪制。一旦開始,就會把上次繪制的節(jié)點清除。
//按下 void GraphicsPainter::mousePressEvent(QMouseEvent *e) { if(bDraw) { if(!bLeftClick) { pointList.clear(); bLeftClick = true; } } //qDebug()<<"Press"; }
一旦鼠標松開,就可以確定一個節(jié)點,此時需要調用update()進行重繪:
//松開 void GraphicsPainter::mouseReleaseEvent(QMouseEvent *e) { if(bDraw&&bLeftClick) { pointList.push_back(QPointF(e->x(), e->y())); bMove = false; this->update(); } //qDebug()<<"Release"; }
當開始進行繪制后,移動鼠標就會處于繪制時的鼠標移動狀態(tài),這時就會確定bMove為true,重繪事件就會將該鼠標點繪制出來,從而達到待選節(jié)點的效果:
//移動 void GraphicsPainter::mouseMoveEvent(QMouseEvent *e) { if(bDraw&&bLeftClick) { movePoint = e->pos(); bMove = true; this->update(); } //qDebug()<<"Move"; }
鼠標雙擊后,將第一個點加入到當前多邊形的節(jié)點中后,達到首尾相連的效果,此時就會結束繪制:
//雙擊 void GraphicsPainter::mouseDoubleClickEvent(QMouseEvent *event) { if(bDraw) { bLeftClick = false; pointList.push_back(pointList[0]); this->update(); singalDrawOver(); } //qDebug()<<"DoubleClick"; }
這里一定要注意,當進行雙擊操作時,首先會觸發(fā)一次mousePressEvent,然后觸發(fā)一次mouseReleaseEvent,接著才會觸發(fā)一次mouseDoubleClickEvent,最后還會觸發(fā)一次mouseReleaseEvent。所以這就是這里設置bLeftClick這個參數(shù)原因:當觸發(fā)mouseDoubleClickEvent后,bLeftClick設置為false,第二次觸發(fā)mouseReleaseEvent時內部就不會在做任何操作了。
3. 結果
最終運行的結果如下所示:
到此這篇關于Qt實現(xiàn)繪制一個簡單多邊形的示例代碼的文章就介紹到這了,更多相關Qt繪制多邊形內容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關文章希望大家以后多多支持腳本之家!
相關文章
C++基于蔡基姆拉爾森計算公式實現(xiàn)由年月日確定周幾的方法示例
這篇文章主要介紹了C++基于蔡基姆拉爾森計算公式實現(xiàn)由年月日確定周幾的方法,涉及C++針對日期時間的數(shù)值運算相關操作技巧,需要的朋友可以參考下2017-07-07Objective-C中常用的結構體NSRange,NSPoint,NSSize(CGSize),NSRect實例分析
這篇文章主要介紹了Objective-C中常用的結構體NSRange,NSPoint,NSSize(CGSize),NSRect實例分析,有助于更加直觀的理解Object-C常用的結構體,需要的朋友可以參考下2014-07-07Qt基礎開發(fā)之QString與QByteArray詳細用法與區(qū)別及QString QByteArray互轉
這篇文章主要介紹了Qt基礎開發(fā)之QString與QByteArray詳細用法與區(qū)別及QString QByteArray互轉,需要的朋友可以參考下2020-03-03linux c語言操作數(shù)據(jù)庫(連接sqlite數(shù)據(jù)庫)
linux下c語言操作sqlite數(shù)據(jù)庫實例方法,大家參考使用吧2013-12-12