c/c++语言开发共享使用QT绘制一个多边形

QT绘制多边形的实例,通过这个实例学习了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绘制一个多边形

本文来自网络收集,不代表计算机技术网立场,如涉及侵权请联系管理员删除。

ctvol管理联系方式QQ:251552304

本文章地址:https://www.ctvol.com/c-cdevelopment/600362.html

(0)
上一篇 2021年5月9日
下一篇 2021年5月9日

精彩推荐