網(wǎng)站首頁 編程語言 正文
1. 概述
可以通過QT的重繪事件和鼠標(biāo)事件來繪制多邊形,最簡單的辦法就是在繼承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)開始左鍵點擊,同時標(biāo)識是否開始進行繪制
bool bMove; //是否處于繪制時的鼠標(biāo)移動狀態(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標(biāo)識是否處于繪制時的鼠標(biāo)移動狀態(tài),只有鼠標(biāo)左鍵點擊后才會確定為真正的節(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);
}
}
鼠標(biāo)按下事件中,主要是通過bLeftClick值來確定是否已經(jīng)處于左鍵點擊狀態(tài),同時還能標(biāo)識是否開始進行繪制。一旦開始,就會把上次繪制的節(jié)點清除。
//按下
void GraphicsPainter::mousePressEvent(QMouseEvent *e)
{
if(bDraw)
{
if(!bLeftClick)
{
pointList.clear();
bLeftClick = true;
}
}
//qDebug()<<"Press";
}
一旦鼠標(biāo)松開,就可以確定一個節(jié)點,此時需要調(diào)用update()進行重繪:
//松開
void GraphicsPainter::mouseReleaseEvent(QMouseEvent *e)
{
if(bDraw&&bLeftClick)
{
pointList.push_back(QPointF(e->x(), e->y()));
bMove = false;
this->update();
}
//qDebug()<<"Release";
}
當(dāng)開始進行繪制后,移動鼠標(biāo)就會處于繪制時的鼠標(biāo)移動狀態(tài),這時就會確定bMove為true,重繪事件就會將該鼠標(biāo)點繪制出來,從而達到待選節(jié)點的效果:
//移動
void GraphicsPainter::mouseMoveEvent(QMouseEvent *e)
{
if(bDraw&&bLeftClick)
{
movePoint = e->pos();
bMove = true;
this->update();
}
//qDebug()<<"Move";
}
鼠標(biāo)雙擊后,將第一個點加入到當(dāng)前多邊形的節(jié)點中后,達到首尾相連的效果,此時就會結(jié)束繪制:
//雙擊
void GraphicsPainter::mouseDoubleClickEvent(QMouseEvent *event)
{
if(bDraw)
{
bLeftClick = false;
pointList.push_back(pointList[0]);
this->update();
singalDrawOver();
}
//qDebug()<<"DoubleClick";
}
這里一定要注意,當(dāng)進行雙擊操作時,首先會觸發(fā)一次mousePressEvent,然后觸發(fā)一次mouseReleaseEvent,接著才會觸發(fā)一次mouseDoubleClickEvent,最后還會觸發(fā)一次mouseReleaseEvent。所以這就是這里設(shè)置bLeftClick這個參數(shù)原因:當(dāng)觸發(fā)mouseDoubleClickEvent后,bLeftClick設(shè)置為false,第二次觸發(fā)mouseReleaseEvent時內(nèi)部就不會在做任何操作了。
3. 結(jié)果
最終運行的結(jié)果如下所示:
原文鏈接:https://blog.csdn.net/m0_60259116/article/details/128007965
相關(guān)推薦
- 2022-04-06 遠程過程調(diào)用RPC基本概念及實現(xiàn)原理_其它綜合
- 2022-04-04 Python數(shù)據(jù)處理-導(dǎo)入導(dǎo)出excel數(shù)據(jù)_python
- 2022-10-16 Python?re.findall中正則表達式(.*?)和參數(shù)re.S使用_python
- 2023-06-17 python?__init__與?__new__的區(qū)別_python
- 2022-12-31 Android權(quán)限機制深入分析講解_Android
- 2024-03-18 JDK版本對應(yīng)其bytecode version (major version)
- 2022-08-16 python切片操作方法的實例總結(jié)_python
- 2022-04-23 C#多線程系列之a(chǎn)sync和await用法詳解_C#教程
- 最近更新
-
- window11 系統(tǒng)安裝 yarn
- 超詳細win安裝深度學(xué)習(xí)環(huán)境2025年最新版(
- Linux 中運行的top命令 怎么退出?
- MySQL 中decimal 的用法? 存儲小
- get 、set 、toString 方法的使
- @Resource和 @Autowired注解
- Java基礎(chǔ)操作-- 運算符,流程控制 Flo
- 1. Int 和Integer 的區(qū)別,Jav
- spring @retryable不生效的一種
- Spring Security之認證信息的處理
- Spring Security之認證過濾器
- Spring Security概述快速入門
- Spring Security之配置體系
- 【SpringBoot】SpringCache
- Spring Security之基于方法配置權(quán)
- redisson分布式鎖中waittime的設(shè)
- maven:解決release錯誤:Artif
- restTemplate使用總結(jié)
- Spring Security之安全異常處理
- MybatisPlus優(yōu)雅實現(xiàn)加密?
- Spring ioc容器與Bean的生命周期。
- 【探索SpringCloud】服務(wù)發(fā)現(xiàn)-Nac
- Spring Security之基于HttpR
- Redis 底層數(shù)據(jù)結(jié)構(gòu)-簡單動態(tài)字符串(SD
- arthas操作spring被代理目標(biāo)對象命令
- Spring中的單例模式應(yīng)用詳解
- 聊聊消息隊列,發(fā)送消息的4種方式
- bootspring第三方資源配置管理
- GIT同步修改后的遠程分支