Qt實(shí)現(xiàn)繪制多個(gè)設(shè)備的流量曲線圖詳解
一、說(shuō)明
在實(shí)際項(xiàng)目中,主要是使用Qt開發(fā)CS程序,當(dāng)然主要是客戶端。公司項(xiàng)目中有這個(gè)需求是實(shí)時(shí)顯示多個(gè)設(shè)備的流量曲線圖,設(shè)備將流量信息發(fā)給服務(wù)端,服務(wù)端再將信息通過(guò)Socket發(fā)給Qt客戶端,Qt客戶端通過(guò)Socket接收后實(shí)時(shí)顯示在程序的一個(gè)窗口上;這個(gè)顯示是以曲線圖的展示方式。
二、界面模型
接到這個(gè)功能需求后,使用的界面模型如下圖所示,圖示已經(jīng)標(biāo)示的很清楚了,我就不多詳細(xì)描述了:
三、功能分析
1、由于設(shè)備較多,超過(guò)100臺(tái),所以不可能每個(gè)設(shè)備的流量曲線都用一種顏色,因此只選擇幾種比較明顯的顏色作為設(shè)備的流量曲線顏色,每次上來(lái)一個(gè)設(shè)備,就用其中的一種顏色繪制曲線。
2、使用QSS來(lái)設(shè)置部件的樣式信息,如前景、背景、被選擇時(shí)、鼠標(biāo)移動(dòng)時(shí)等等。
3、用一個(gè)部件用作專門的繪制部件,該部件放在窗口中,因此安裝事件過(guò)濾器,用于重繪子部件信息,繪制曲線圖。
4、處理設(shè)備上線/下線的網(wǎng)絡(luò)消息以及設(shè)備主動(dòng)發(fā)送的動(dòng)態(tài)流量信息;處理Qt客戶端與服務(wù)端的連接/斷開事件。
四、界面效果
開發(fā)出來(lái)的最終效果圖如下所示:
初始所有設(shè)備的流量圖如下圖
選擇設(shè)備名為a5的流量圖,其中a5設(shè)備的流量曲線加粗,背景半透明等效果如下圖
選擇設(shè)備名為a7的流量圖,其中a7設(shè)備的流量曲線加粗,背景半透明等效果如下圖
五、主要代碼
//消息過(guò)濾,主要用于重繪子控件,過(guò)濾Paint事件 bool QAPRTCurWidget::eventFilter(QObject *watched, QEvent *event) { if(watched==ui->widget_rxtx && event->type()==QEvent::Paint) { updateWidgetRTX(); } return QFrame::eventFilter(watched,event); }
//繪圖操作 void QAPRTCurWidget::updateWidgetRTX() { QPainter painter(ui->widget_rxtx); painter.setFont(QFont("Times", , QFont::Bold)); //繪制背景顏色 painterBackground(painter); //畫最左邊一條虛線,用于和List隔開 painterLeftDashLine(painter); //畫縱坐標(biāo)文本標(biāo)識(shí) updateVTextID(painter); //畫縱坐標(biāo)文本刻度以及橫縱坐標(biāo)軸 updateVTextMarkAndCoord(painter); //畫RX曲線 paintRXLineInfo(painter); //畫TX曲線 paintTXLineInfo(painter); }
//畫縱坐標(biāo)文本刻度以及橫縱坐標(biāo)軸 void QAPRTCurWidget::updateVTextMarkAndCoord(QPainter &painter) { painter.save(); //繪圖區(qū)間的實(shí)際高度(部件高度-頂部間隔-底部間隔) int nActPaintHeight = ui->widget_rxtx->height()-INTERVAL_WIDGET_TOP-INTERVAL_WIDGET_BOTTOM; //每隔的間隔高度 float fIntervalHeight = ((float)nActPaintHeight)/(m_nVSingleLinePointCount-); float fYPointForZero = ui->widget_rxtx->height()-INTERVAL_WIDGET_BOTTOM; double dDivideValue = ; if(ui->toolButton_rxflow->isChecked()) { dDivideValue = ((double)nRXMaxValue)/(m_nVSingleLinePointCount-); } if(ui->toolButton_txflow->isChecked()) { dDivideValue = ((double)nTXMaxValue)/(m_nVSingleLinePointCount-); } for(int nIndex=;nIndex<m_nVSingleLinePointCount;++nIndex) { //設(shè)置文本顏色 painter.setPen(TEXTCOLOR_WIDGET_PAINT); //將原來(lái)的字體變小,設(shè)置為8 QFont objFont = painter.font(); objFont.setPointSize(); painter.setFont(objFont); //畫文本,加3的目的是為了是其和橫線能保持中間持平 painter.drawText(INTERVAL_VMARK_LEFT,fYPointForZero-nIndex*fIntervalHeight+,QCommonOP::getKMStrForBit(dDivideValue*nIndex)); //設(shè)置橫線顏色 painter.setPen(COORDCOLOR_WIDGET_PAINT); //畫橫線(第一條和最后一條為實(shí)線,中間的為虛線) QPen objPen = painter.pen(); if(==nIndex || (m_nVSingleLinePointCount-)==nIndex) { objPen.setStyle(Qt::SolidLine); } else { objPen.setStyle(Qt::DashLine); } painter.setPen(objPen); float x1 = ui->widget_rxtx->width()-INTERVAL_WIDGET_RIGHT; float y1 = fYPointForZero-nIndex*fIntervalHeight; painter.drawLine(INTERVAL_HCOORD_LEFT,fYPointForZero-nIndex*fIntervalHeight,x1,y1); } int nActPaintWidth = ui->widget_rxtx->width()-INTERVAL_HCOORD_LEFT-INTERVAL_WIDGET_RIGHT; //每隔的間隔高度--橫向:注意使用(float)nActPaintWidth)作為分子,即浮點(diǎn)數(shù) float fIntervalWidth = ((float)nActPaintWidth)/(m_nHSingleLinePointCount-); for(int nIndex=;nIndex<m_nHSingleLinePointCount;++nIndex) { QPen objPen = painter.pen(); if(==nIndex || (m_nHSingleLinePointCount-)==nIndex) { objPen.setStyle(Qt::SolidLine); } else { objPen.setStyle(Qt::DashLine); } painter.setPen(objPen); int nXPoint = INTERVAL_HCOORD_LEFT+nIndex*fIntervalWidth; painter.drawLine(nXPoint,INTERVAL_WIDGET_TOP,nXPoint,ui->widget_rxtx->height()-INTERVAL_WIDGET_BOTTOM); } painter.restore(); }
到此這篇關(guān)于Qt實(shí)現(xiàn)繪制多個(gè)設(shè)備的流量曲線圖詳解的文章就介紹到這了,更多相關(guān)Qt繪制流量曲線圖內(nèi)容請(qǐng)搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
相關(guān)文章
關(guān)于memcpy和memmove的一點(diǎn)重要說(shuō)明
下面小編就為大家?guī)?lái)一篇關(guān)于memcpy和memmove的一點(diǎn)重要說(shuō)明。小編覺(jué)得挺不錯(cuò)的,現(xiàn)在就分享給大家,也給大家做個(gè)參考。一起跟隨小編過(guò)來(lái)看看吧2016-12-12C++中異常機(jī)制的實(shí)現(xiàn)機(jī)制詳解
這篇文章主要給大家介紹了關(guān)于C++中異常機(jī)制的實(shí)現(xiàn)機(jī)制的相關(guān)資料,文中通過(guò)圖文以及示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來(lái)一起學(xué)習(xí)學(xué)習(xí)吧2018-06-06C++實(shí)現(xiàn)簡(jiǎn)單的掃雷游戲(控制臺(tái)版)
這篇文章主要為大家詳細(xì)介紹了C++實(shí)現(xiàn)簡(jiǎn)單的掃雷游戲,控制臺(tái)版的掃雷游戲希望大家喜歡,文中示例代碼介紹的非常詳細(xì),具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下2016-05-05淺談Windows系統(tǒng)下C語(yǔ)言編程中Glib庫(kù)的使用
這篇文章主要介紹了Windows系統(tǒng)下C語(yǔ)言編程中Glib庫(kù)的使用,Glib庫(kù)在多線程編程中經(jīng)常可以用到,需要的朋友可以參考下2016-02-02C/C++實(shí)現(xiàn)通訊錄管理系統(tǒng)(附源碼)
這篇文章主要為大家詳細(xì)介紹了如何利用C++實(shí)現(xiàn)通訊錄管理系統(tǒng),文中示例代碼介紹的非常詳細(xì),具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下2022-12-12C++ 詳細(xì)講解stack與queue的模擬實(shí)現(xiàn)
C++ Stack(堆棧) 是一個(gè)容器類的改編,為程序員提供了堆棧的全部功能,也就是說(shuō)實(shí)現(xiàn)了一個(gè)先進(jìn)后出(FILO)的數(shù)據(jù)結(jié)構(gòu),許多程序都使用了 queue 容器。queue 容器可以用來(lái)表示超市的結(jié)賬隊(duì)列或服務(wù)器上等待執(zhí)行的數(shù)據(jù)庫(kù)事務(wù)隊(duì)列2022-04-04