程序師世界是廣大編程愛好者互助、分享、學習的平台,程序師世界有你更精彩!
首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫知識
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
 程式師世界 >> 編程語言 >> C語言 >> C++ >> C++入門知識 >> 使用Qt開發繪制多個設備的流量曲線圖(附帶項目圖),

使用Qt開發繪制多個設備的流量曲線圖(附帶項目圖),

編輯:C++入門知識

使用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 }
復制代碼

  1. 上一頁:
  2. 下一頁:
Copyright © 程式師世界 All Rights Reserved