Qt Charts 动态实时显示多条折线图

时间:2024-03-23 19:16:20

老早就做了功能,在做第二次的时候发现还是将其记录下来,以免日后时间过长遗忘了

一、在项目的.pro添加的是

QT += charts

并且在程序的开头(不是.pro文件)加上一句 using namespace Qtcharts或者一个宏 QT_CHARTS_USE_NAMESPACE

二、界面如图所示

Qt Charts 动态实时显示多条折线图

因为这只是一个demo,没有与其他地方通讯,所以就固定显示,如果你们以后有需求,只需要返回需要显示的数据即可

三、

Qt Charts 动态实时显示多条折线图

其中

void MainWindow::SeriesInit(qint8 ch)

{

//新建一条折现线

m_series[ch] = new QLineSeries;

//添加到chart

m_chart->addSeries(m_series[ch]);

switch(ch)

{

//设置颜色和线大小

case 0:m_series[ch]->setPen(QPen(Qt::black,2,Qt::SolidLine));break;

case 1:m_series[ch]->setPen(QPen(Qt::red,2,Qt::SolidLine));break;

case 2:m_series[ch]->setPen(QPen(Qt::green,2,Qt::SolidLine));break;

case 3:m_series[ch]->setPen(QPen(Qt::blue,2,Qt::SolidLine));break;

case 4:m_series[ch]->setPen(QPen(Qt::cyan,2,Qt::SolidLine));break;

case 5:m_series[ch]->setPen(QPen(Qt::magenta,2,Qt::SolidLine));break;

case 6:m_series[ch]->setPen(QPen(Qt::yellow,2,Qt::SolidLine));break;

case 7:m_series[ch]->setPen(QPen(Qt::gray,2,Qt::SolidLine));break;

}

//将其添加到坐标轴

m_chart->setAxisX(axisX,m_series[ch]);

m_chart->setAxisY(axisY,m_series[ch]);

//关联显示函数

connect(m_series[ch], SIGNAL(hovered(QPointF, bool)), this, SLOT(showPointData(QPointF,bool)));

}

放大缩小,一个鼠标滚轮事件:

void MainWidget::wheelEvent(QWheelEvent *event)
{
    if (event->delta() > 0) {
        chart->zoom(1.1);
    } else {
        chart->zoom(10.0/11);
    }

    QWidget::wheelEvent(event);
}

其实就调用了一个zoomReset()函数:

void ChartView::mousePressEvent(QMouseEvent *event)
{
    if (event->button() & Qt::LeftButton) {
        isClicking = true;
    } else if (event->button() & Qt::RightButton) {
        chart()->zoomReset();
    }

    QChartView::mousePressEvent(event);
}

图像拖拽
就是一个mousePressEvent和mouseMoveEvent事件,鼠标按下了把标志位变为true,然后在鼠标Move的时候检测标志位是否为true,如果是就根据坐标计算scroll值:

void ChartView::mouseMoveEvent(QMouseEvent *event)
{
    int x, y;

    if (isClicking) {
        if (xOld == 0 && yOld == 0) {

        } else {
            x = event->x() - xOld;
            y = event->y() - yOld;
            chart()->scroll(-x, y);
        }

        xOld = event->x();
        yOld = event->y();

        return;
    }

    QChartView::mouseMoveEvent(event);
}

但是如果先拖拽再放大缩小,还原的时候是已拖拽的地方为初始位置,故在没有放大缩小的时候不准拖拽

int x, y;
if (isClicking) {

if (xOld == 0 && yOld == 0) { }

else{

if(isZooninOrOut){

x = event->x() - xOld;

y = event->y() - yOld;

chart()->scroll(-x, y);}

}

xOld = event->x();

yOld = event->y();

return;

}QChartView::mouseMoveEvent(event);


void MainWindow::updateData()
{
    int i,j;
    QVector<QPointF> oldData[8];
    QVector<QPointF> data[8];
    qint64 size[8];
    if(isVisible())
    {
        if(currentChangel == 8)
        {
            for(j = 0;j < 8;j++)
            {
                oldData[j] = m_series[j]->pointsVector();
                if (oldData[j].size() < 100)
                {
                    data[j] = oldData[j];
                }
                else
                {
                    /* 添加之前老的数据到新的vector中,不复制最前的数据,即每次替换前面的数据
                     * 由于这里每次只添加1个数据,所以为1,使用时根据实际情况修改
                     */

                    for (i = 1; i < oldData[j].size(); ++i) {
                        data[j].append(QPointF(i - 1, oldData[j].at(i).y()));
                    }

                }
                size[j] = data[j].size();
            }
            /* 这里表示插入新的数据,因为每次只插入1个,这里为i < 1,
             * 但为了后面方便插入多个数据,先这样写
             */

            for(i = 0; i < 1; ++i){
                for(j = 0;j < 8;j++)
                {
                    data[j].append(QPointF(i + size[j], GetTempData(j) ));
                }
            }
            for(j = 0;j < 8;j++)
            {
                m_series[j]->replace(data[j]);
            }
        }
        else
        {
            lastChangel =currentChangel;
            oldData[currentChangel] = m_series[currentChangel]->pointsVector();
            if (oldData[currentChangel].size() < 100)
            {
                data[currentChangel] = oldData[currentChangel];
            }
            else
            {
                for (i = 1; i < oldData[currentChangel].size(); ++i) {
                    data[currentChangel].append(QPointF(i - 1, oldData[currentChangel].at(i).y()));
                }

            }
            size[currentChangel] = data[currentChangel].size();
            for(i = 0; i < 1; ++i)
            {
                data[currentChangel].append(QPointF(i + size[currentChangel], GetTempData(currentChangel) ));
            }
            m_series[currentChangel]->replace(data[currentChangel]);
        }
    }

}

暂停/继续

if (QObject::sender() == ui->Btn_Stop) {

if (!isStopping) {

TempTime->stop();

ui->Btn_Stop->setText("继续");

} else {

TempTime->start();

ui->Btn_Stop->setText("暂停");

}

isStopping = !isStopping; }

这里要添加一句:在下载的代码里,切换通道的方法我觉得不好了,其实在切换通道,界面显示的是可以清空的,不用移除,

if(lastChangel ==8)

{

for(qint8 i = 0;i <8;i++)

{

//上一个显示了8个通道,那么就要所有的都清空

m_series[i]->clear();

}

}

else

{

//不然只需清空上一个通道的线

m_series[lastChangel]->clear();

}

主要功能就是:8条通道显示,保存当前曲线,通道切换,暂停/继续,区间变换,数据动态更新,放大缩小,比例复原,坐标显示,图像拖拽

如果有需要的可以下载:https://download.csdn.net/download/qq_41399894/10665120

参考:https://blog.csdn.net/q294971352/article/details/78558987,他也有一个demo,我的本来是不要C币的,后来不知道为什么,有段时间没有了,再出来的时候自动给我加了7个C币