• 使用Qt开发绘制多个设备的流量曲线图(附带项目图)


    一、说明:

    在实际项目中,主要是使用Qt开发CS程序,当然主要是客户端。公司项目中有这个需求是实时显示多个设备的流量曲线图,设备将流量信息发给服务端,服务端再将信息通过Socket发给Qt客户端,Qt客户端通过Socket接收后实时显示在程序的一个窗口上;这个显示是以曲线图的展示方式。

    二、界面模型
    接到这个功能需求后,使用的界面模型如下图所示,图示已经标示的很清楚了,我就不多详细描述了:


    三、功能分析

    1、由于设备较多,超过100台,所以不可能每个设备的流量曲线都用一种颜色,因此只选择几种比较明显的颜色作为设备的流量曲线颜色,每次上来一个设备,就用其中的一种颜色绘制曲线。

    2、使用QSS来设置部件的样式信息,如前景、背景、被选择时、鼠标移动时等等。

    3、用一个部件用作专门的绘制部件,该部件放在窗口中,因此安装事件过滤器,用于重绘子部件信息,绘制曲线图。

    4、处理设备上线/下线的网络消息以及设备主动发送的动态流量信息;处理Qt客户端与服务端的连接/断开事件。

    四、界面效果

    开发出来的最终效果图如下所示:

    初始所有设备的流量图如下图

    选择设备名为a5的流量图,其中a5设备的流量曲线加粗,背景半透明等效果如下图

    选择设备名为a7的流量图,其中a7设备的流量曲线加粗,背景半透明等效果如下图


    五、主要代码

    1 //消息过滤,主要用于重绘子控件,过滤Paint事件
    2 bool QAPRTCurWidget::eventFilter(QObject *watched, QEvent *event)
    3 {
    4     if(watched==ui->widget_rxtx && event->type()==QEvent::Paint)
    5     {
    6         updateWidgetRTX();
    7     }
    8     return QFrame::eventFilter(watched,event);
    9 }
     1 //绘图操作
     2 void QAPRTCurWidget::updateWidgetRTX()
     3 {
     4     QPainter painter(ui->widget_rxtx);
     5     painter.setFont(QFont("Times", 12, QFont::Bold));
     6     //绘制背景颜色
     7     painterBackground(painter);
     8     //画最左边一条虚线,用于和List隔开
     9     painterLeftDashLine(painter);
    10     //画纵坐标文本标识
    11     updateVTextID(painter);
    12     //画纵坐标文本刻度以及横纵坐标轴
    13     updateVTextMarkAndCoord(painter);
    14     //画RX曲线
    15     paintRXLineInfo(painter);
    16     //画TX曲线
    17     paintTXLineInfo(painter);
    18 }
     1 //画纵坐标文本刻度以及横纵坐标轴
     2 void QAPRTCurWidget::updateVTextMarkAndCoord(QPainter &painter)
     3 {
     4     painter.save();
     5     //绘图区间的实际高度(部件高度-顶部间隔-底部间隔)
     6     int nActPaintHeight = ui->widget_rxtx->height()-INTERVAL_WIDGET_TOP-INTERVAL_WIDGET_BOTTOM;
     7     //每隔的间隔高度
     8     float fIntervalHeight = ((float)nActPaintHeight)/(m_nVSingleLinePointCount-1);
     9     float fYPointForZero = ui->widget_rxtx->height()-INTERVAL_WIDGET_BOTTOM;
    10     double dDivideValue = 0;
    11     if(ui->toolButton_rxflow->isChecked())
    12     {
    13         dDivideValue = ((double)nRXMaxValue)/(m_nVSingleLinePointCount-1);
    14     }
    15     if(ui->toolButton_txflow->isChecked())
    16     {
    17         dDivideValue = ((double)nTXMaxValue)/(m_nVSingleLinePointCount-1);
    18     }
    19     for(int nIndex=0;nIndex<m_nVSingleLinePointCount;++nIndex)
    20     {
    21         //设置文本颜色
    22         painter.setPen(TEXTCOLOR_WIDGET_PAINT);
    23         //将原来的字体变小,设置为8
    24         QFont objFont = painter.font();
    25         objFont.setPointSize(8);
    26         painter.setFont(objFont);
    27         //画文本,加3的目的是为了是其和横线能保持中间持平
    28         painter.drawText(INTERVAL_VMARK_LEFT,fYPointForZero-nIndex*fIntervalHeight+3,QCommonOP::getKMStrForBit(dDivideValue*nIndex));
    29         //设置横线颜色
    30         painter.setPen(COORDCOLOR_WIDGET_PAINT);
    31         //画横线(第一条和最后一条为实线,中间的为虚线)
    32         QPen objPen = painter.pen();
    33         if(0==nIndex || (m_nVSingleLinePointCount-1)==nIndex)
    34         {
    35            objPen.setStyle(Qt::SolidLine);
    36         }
    37         else
    38         {
    39             objPen.setStyle(Qt::DashLine);
    40         }
    41         painter.setPen(objPen);
    42         float x1 = ui->widget_rxtx->width()-INTERVAL_WIDGET_RIGHT;
    43         float y1 = fYPointForZero-nIndex*fIntervalHeight;
    44         painter.drawLine(INTERVAL_HCOORD_LEFT,fYPointForZero-nIndex*fIntervalHeight,x1,y1);
    45     }
    46     int nActPaintWidth = ui->widget_rxtx->width()-INTERVAL_HCOORD_LEFT-INTERVAL_WIDGET_RIGHT;
    47     //每隔的间隔高度--横向:注意使用(float)nActPaintWidth)作为分子,即浮点数
    48     float fIntervalWidth = ((float)nActPaintWidth)/(m_nHSingleLinePointCount-1);
    49     for(int nIndex=0;nIndex<m_nHSingleLinePointCount;++nIndex)
    50     {
    51         QPen objPen = painter.pen();
    52         if(0==nIndex || (m_nHSingleLinePointCount-1)==nIndex)
    53         {
    54            objPen.setStyle(Qt::SolidLine);
    55         }
    56         else
    57         {
    58             objPen.setStyle(Qt::DashLine);
    59         }
    60         painter.setPen(objPen);
    61         int nXPoint = INTERVAL_HCOORD_LEFT+nIndex*fIntervalWidth;
    62         painter.drawLine(nXPoint,INTERVAL_WIDGET_TOP,nXPoint,ui->widget_rxtx->height()-INTERVAL_WIDGET_BOTTOM);
    63     }
    64     painter.restore();
    65 }
  • 相关阅读:
    Bootstrap历练实例:带有下拉菜单的标签和胶囊导航
    python学习网址
    /mnt/sdcard 是什么东西
    tornado中文教程
    ssh免密码登录远程服务器(不采用securecrt登录)
    接口测试博客
    [python学习篇] [os模块] [2]删除文件夹
    解压文件夹python
    adb pull 文件夹的时候注意
    [uiautomator篇][python调用java][1]应用下载的插件需要很长时间问题解决
  • 原文地址:https://www.cnblogs.com/appsucc/p/3542557.html
Copyright © 2020-2023  润新知