1. 程式人生 > 實用技巧 >Qt Charts 動態實時顯示多條折線圖

Qt Charts 動態實時顯示多條折線圖

老早就做了功能,在做第二次的時候發現還是將其記錄下來,以免日後時間過長遺忘了

一、在專案的.pro新增的是

QT += charts

並且在程式的開頭(不是.pro檔案)加上一句using namespace Qtcharts或者一個巨集QT_CHARTS_USE_NAMESPACE

二、介面如圖所示

因為這只是一個demo,沒有與其他地方通訊,所以就固定顯示,如果你們以後有需求,只需要返回需要顯示的資料即可

三、

其中

  1 void MainWindow::SeriesInit(qint8 ch)
  2 
  3 {
  4 //新建一條折現線
  5 
  6 m_series[ch] = new
QLineSeries; 7 8 //新增到chart 9 10 m_chart->addSeries(m_series[ch]); 11 12 switch(ch) 13 14 { 15 //設定顏色和線大小 16 17 case 0:m_series[ch]->setPen(QPen(Qt::black,2,Qt::SolidLine));break; 18 19 case 1:m_series[ch]->setPen(QPen(Qt::red,2,Qt::SolidLine));break; 20 21 case 2:m_series[ch]->setPen(QPen(Qt::green,2
,Qt::SolidLine));break; 22 23 case 3:m_series[ch]->setPen(QPen(Qt::blue,2,Qt::SolidLine));break; 24 25 case 4:m_series[ch]->setPen(QPen(Qt::cyan,2,Qt::SolidLine));break; 26 27 case 5:m_series[ch]->setPen(QPen(Qt::magenta,2,Qt::SolidLine));break; 28 29 case 6:m_series[ch]->setPen(QPen(Qt::yellow,2
,Qt::SolidLine));break; 30 31 case 7:m_series[ch]->setPen(QPen(Qt::gray,2,Qt::SolidLine));break; 32 33 } 34 35 //將其新增到座標軸 36 37 m_chart->setAxisX(axisX,m_series[ch]); 38 39 m_chart->setAxisY(axisY,m_series[ch]); 40 41 //關聯顯示函式 42 43 connect(m_series[ch], SIGNAL(hovered(QPointF, bool)), this, SLOT(showPointData(QPointF,bool))); 44 45 } 46 47 放大縮小,一個滑鼠滾輪事件: 48 49 void MainWidget::wheelEvent(QWheelEvent *event) 50 { 51 if (event->delta() > 0) { 52 chart->zoom(1.1); 53 } else { 54 chart->zoom(10.0/11); 55 } 56 57 QWidget::wheelEvent(event); 58 } 59 60 其實就呼叫了一個zoomReset()函式: 61 62 void ChartView::mousePressEvent(QMouseEvent *event) 63 { 64 if (event->button() & Qt::LeftButton) { 65 isClicking = true; 66 } else if (event->button() & Qt::RightButton) { 67 chart()->zoomReset(); 68 } 69 70 QChartView::mousePressEvent(event); 71 } 72 73 影象拖拽 74 就是一個mousePressEvent和mouseMoveEvent事件,滑鼠按下了把標誌位變為true,然後在滑鼠Move的時候檢測標誌位是否為true,如果是就根據座標計算scroll值: 75 76 void ChartView::mouseMoveEvent(QMouseEvent *event) 77 { 78 int x, y; 79 80 if (isClicking) { 81 if (xOld == 0 && yOld == 0) { 82 } else { 83 x = event->x() - xOld; 84 y = event->y() - yOld; 85 chart()->scroll(-x, y); 86 } 87 88 xOld = event->x(); 89 yOld = event->y(); 90 91 return; 92 } 93 94 QChartView::mouseMoveEvent(event); 95 } 96 97 但是如果先拖拽再放大縮小,還原的時候是已拖拽的地方為初始位置,故在沒有放大縮小的時候不準拖拽 98 99 int x, y; 100 if (isClicking) { 101 if (xOld == 0 && yOld == 0) { } 102 103 else{ 104 if(isZooninOrOut){ 105 x = event->x() - xOld; 106 107 y = event->y() - yOld; 108 109 chart()->scroll(-x, y);} 110 111 } 112 113 xOld = event->x(); 114 115 yOld = event->y(); 116 117 return; 118 119 }QChartView::mouseMoveEvent(event); 120 121 122 void MainWindow::updateData() 123 { 124 int i,j; 125 QVector<QPointF> oldData[8]; 126 QVector<QPointF> data[8]; 127 qint64 size[8]; 128 if(isVisible()) 129 { 130 if(currentChangel == 8) 131 { 132 for(j = 0;j < 8;j++) 133 { 134 oldData[j] = m_series[j]->pointsVector(); 135 if (oldData[j].size() < 100) 136 { 137 data[j] = oldData[j]; 138 } 139 else 140 { 141 /* 新增之前老的資料到新的vector中,不復制最前的資料,即每次替換前面的資料 142 * 由於這裡每次只新增1個數據,所以為1,使用時根據實際情況修改 143 */ 144 145 for (i = 1; i < oldData[j].size(); ++i) { 146 data[j].append(QPointF(i - 1, oldData[j].at(i).y())); 147 } 148 149 } 150 size[j] = data[j].size(); 151 } 152 /* 這裡表示插入新的資料,因為每次只插入1個,這裡為i < 1, 153 * 但為了後面方便插入多個數據,先這樣寫 154 */ 155 156 for(i = 0; i < 1; ++i){ 157 for(j = 0;j < 8;j++) 158 { 159 data[j].append(QPointF(i + size[j], GetTempData(j) )); 160 } 161 } 162 for(j = 0;j < 8;j++) 163 { 164 m_series[j]->replace(data[j]); 165 } 166 } 167 else 168 { 169 lastChangel =currentChangel; 170 oldData[currentChangel] = m_series[currentChangel]->pointsVector(); 171 if (oldData[currentChangel].size() < 100) 172 { 173 data[currentChangel] = oldData[currentChangel]; 174 } 175 else 176 { 177 for (i = 1; i < oldData[currentChangel].size(); ++i) { 178 data[currentChangel].append(QPointF(i - 1, oldData[currentChangel].at(i).y())); 179 } 180 181 } 182 size[currentChangel] = data[currentChangel].size(); 183 for(i = 0; i < 1; ++i) 184 { 185 data[currentChangel].append(QPointF(i + size[currentChangel], GetTempData(currentChangel) )); 186 } 187 m_series[currentChangel]->replace(data[currentChangel]); 188 } 189 } 190 191 } 192 193 暫停/繼續 194 195 if (QObject::sender() == ui->Btn_Stop) { 196 if (!isStopping) { 197 TempTime->stop(); 198 199 ui->Btn_Stop->setText("繼續"); 200 201 } else { 202 TempTime->start(); 203 204 ui->Btn_Stop->setText("暫停"); 205 206 } 207 208 isStopping = !isStopping; } 209 210 這裡要新增一句:在下載的程式碼裡,切換通道的方法我覺得不好了,其實在切換通道,介面顯示的是可以清空的,不用移除, 211 212 if(lastChangel ==8) 213 214 { 215 for(qint8 i = 0;i <8;i++) 216 217 { 218 //上一個顯示了8個通道,那麼就要所有的都清空 219 220 m_series[i]->clear(); 221 222 } 223 224 } 225 226 else 227 228 { 229 //不然只需清空上一個通道的線 230 231 m_series[lastChangel]->clear(); 232 233 }

主要功能就是:8條通道顯示,儲存當前曲線,通道切換,暫停/繼續,區間變換,資料動態更新,放大縮小,比例復原,座標顯示,影象拖拽