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条通道显示,保存当前曲线,通道切换,暂停/继续,区间变换,数据动态更新,放大缩小,比例复原,坐标显示,图像拖拽


免责声明!

本站转载的文章为个人学习借鉴使用,本站对版权不负任何法律责任。如果侵犯了您的隐私权益,请联系本站邮箱yoyou2525@163.com删除。



 
粤ICP备18138465号  © 2018-2025 CODEPRJ.COM