使用QT绘制一个多边形

1. 概述

可以通过QT的重绘事件和鼠标事件来绘制多边形,最简单的办法就是在继承QWidget的窗体中重写paintEvent、mousePressEvent等事件处理函数。QT提供了图形绘制接口QPainter,通过该接口可以绘制多种图形,包括多边形。

2. 实现

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;             //是否处于绘制状态
    bool bLeftClick;            //是否已经开始左键点击,同时标识是否开始进行绘制
    bool bMove;             //是否处于绘制时的鼠标移动状态

    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();
}

//重新实现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. 解析

在重新实现的重绘事件中,通过QPainter绘制了一系列线组成线串,最后会首尾相连形成多边形。这里的bMove标识是否处于绘制时的鼠标移动状态,只有鼠标左键点击后才会确定为真正的节点:

//重新实现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值来确定是否已经处于左键点击状态,同时还能标识是否开始进行绘制。一旦开始,就会把上次绘制的节点清除。

//按下
void GraphicsPainter::mousePressEvent(QMouseEvent *e)
{
    if(bDraw)
    {
        if(!bLeftClick)
        {
            pointList.clear();
            bLeftClick = true;
        }
    }
    //qDebug()<<"Press";
}

一旦鼠标松开,就可以确定一个节点,此时需要调用update()进行重绘:

//松开
void GraphicsPainter::mouseReleaseEvent(QMouseEvent *e)
{
    if(bDraw&&bLeftClick)
    {
        pointList.push_back(QPointF(e->x(), e->y()));
        bMove = false;
        this->update();
    }
    //qDebug()<<"Release";
}

当开始进行绘制后,移动鼠标就会处于绘制时的鼠标移动状态,这时就会确定bMove为true,重绘事件就会将该鼠标点绘制出来,从而达到待选节点的效果:

//移动
void GraphicsPainter::mouseMoveEvent(QMouseEvent *e)
{
    if(bDraw&&bLeftClick)
    {
        movePoint = e->pos();
        bMove = true;
        this->update();
    }
    //qDebug()<<"Move";
}

鼠标双击后,将第一个点加入到当前多边形的节点中后,达到首尾相连的效果,此时就会结束绘制:

//双击
void GraphicsPainter::mouseDoubleClickEvent(QMouseEvent *event)
{
    if(bDraw)
    {
        bLeftClick = false;
        pointList.push_back(pointList[0]);
        this->update();
        singalDrawOver();
    }
    //qDebug()<<"DoubleClick";
}

这里一定要注意,当进行双击操作时,首先会触发一次mousePressEvent,然后触发一次mouseReleaseEvent,接着才会触发一次mouseDoubleClickEvent,最后还会触发一次mouseReleaseEvent。所以这就是这里设置bLeftClick这个参数原因:当触发mouseDoubleClickEvent后,bLeftClick设置为false,第二次触发mouseReleaseEvent时内部就不会在做任何操作了。

3. 结果

最终运行的结果如下所示:

QT绘制多边形

代码地址

QCustomPlot是一个用于绘制图表的Qt插件,它提供了丰富的功能和灵活的定制选项。要使用QCustomPlot绘制一个多边形,可以按照以下步骤进行操作: 1. 创建一个Qt工程,并将下载的QCustomPlot源文件的.c和.h文件分别添加到源文件和头文件中。 2. 在.pro文件中添加`QT += widgets printsupport`,以便使用QCustomPlot所需的模块。 3. 在UI界面中添加一个新的widget控件,并将其提升为QCustomPlot类。右击鼠标选择“提升为”,然后输入类名称“QCustomPlot”,点击添加并点击提升。 4. 在主要代码中,使用QCustomPlot的函数来绘制多边形。可以使用`QCPItemPolygon`类来创建一个多边形对象,并使用`addPolygon`函数将其添加到QCustomPlot中。在`addPolygon`函数中,传入多边形的顶点坐标即可确定多边形的形状。 下面是一个示例代码,演示了如何使用QCustomPlot绘制一个多边形: ```cpp #include "mainwindow.h" #include "ui_mainwindow.h" #include "qcustomplot.h" MainWindow::MainWindow(QWidget *parent) : QMainWindow(parent), ui(new Ui::MainWindow) { ui->setupUi(this); // 创建QCustomPlot对象 QCustomPlot *customPlot = new QCustomPlot(this); // 添加到UI界面中 ui->verticalLayout->addWidget(customPlot); // 创建多边形对象 QCPItemPolygon *polygon = new QCPItemPolygon(customPlot); // 设置多边形的顶点坐标 QVector<QPointF> points; points << QPointF(0, 0) << QPointF(100, 0) << QPointF(100, 100) << QPointF(0, 100); polygon->setPolygon(QPolygonF(points)); // 设置多边形的样式 QPen pen; pen.setColor(Qt::red); pen.setWidth(2); polygon->setPen(pen); // 刷新绘图 customPlot->replot(); } MainWindow::~MainWindow() { delete ui; } ``` 请注意,以上代码仅为示例,实际使用时需要根据具体需求进行修改和定制。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

charlee44

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值