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

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

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

QT += charts

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

二、界面如图所示

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

三、

其中

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币

  • 26
    点赞
  • 220
    收藏
    觉得还不错? 一键收藏
  • 39
    评论
Qt中,可以使用QChart和QChartView来实现折线图动态显示效果。 首先,创建一个QChart对象用于存储折线图的数据和属性。然后,创建一个QLineSeries对象,并将其添加到QChart中。接下来,创建一个QChartView对象,并将QChart对象设置为其属性。这样就创建了一个折线图显示窗口。 要让折线图动态显示,可以使用QTimer来定时刷新折线图的数据。在每次定时器到达时,更新QLineSeries的数据,并重新绘制折线图。 具体的步骤如下所示: 1. 创建一个QChart对象和一个QLineSeries对象。 2. 将QLineSeries添加到QChart中。 3. 创建一个QChartView对象,并将QChart设置为其属性。 4. 创建一个QTimer对象,并设置定时器的间隔时间。 5. 通过connect函数将QTimer的timeout信号连接到一个槽函数中。 6. 在槽函数中更新折线图的数据,并调用QWidget的update函数重新绘制折线图。 示例代码如下: ```cpp #include <QtCharts> #include <QChartView> #include <QLineSeries> #include <QTimer> int main(int argc, char *argv[]) { QApplication a(argc, argv); QLineSeries *series = new QLineSeries(); QChart *chart = new QChart(); chart->addSeries(series); chart->setTitle("Dynamic Line Chart"); QChartView *chartView = new QChartView(chart); chartView->setRenderHint(QPainter::Antialiasing); chartView->show(); QTimer *timer = new QTimer(); timer->setInterval(1000); QObject::connect(timer, &QTimer::timeout, [=]() { // 更新折线图的数据 *series << QPointF(qrand() % 10, qrand() % 10); chart->update(); }); timer->start(); return a.exec(); } ``` 运行代码后,会显示一个动态折线图的窗口,每隔1秒钟更新一次折线图的数据。可以根据实际需求调整定时器的间隔时间。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 39
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值