(四)QCustomPlot柱形图动态显示实例开发

系列文章目录

提示:这里是该系列文章的所有文章的目录
第一章: (一)QCustomPlot常见属性设置、多曲线绘制、动态曲线绘制、生成游标、矩形放大等功能实现
第二章: (二)QCustomPlot生成热力图/矩阵颜色图
第三章: (三)Qt+QCustomPlot生成上下方向/不同颜色的条形图(柱形图)
第四章 :(四)QCustomPlot柱形图动态显示实例开发



前言

接上一篇文章,在前文中实现的一个柱形图数据都是固定的,无法通过模拟按钮来进行数据的增加,并且数据量较小,无法体现实际项目中所需要的功能。所以在这一篇文章中进行了数据的模拟增加,并且可以动态显示界面,也可以清空图表进行重绘,详细功能实现见文章内容,大家可以参考学习,如有错误之处,欢迎大家批评指正。

项目效果
请添加图片描述


提示:以下是本篇文章正文内容,下面案例可供参考

一、QCustomPlot的提升

本文在ui界面上添加了两个widget控件,并将其提升为QCustomPlot类,具体的提升步骤可见此博客:QCustomPlot常见属性设置、多曲线绘制、动态曲线绘制、生成游标、矩形放大等功能实现
请添加图片描述

由于界面上有多个QCustomPlot,所以在我们的构造函数中需要对这两个控件进行初始化,两个控件背景等等都是一样的,所以这里使用了一个setBarCustomPlot()函数通过输入形参的方式来完成两个控件的初始化,见下文示例完整代码。

void Widget::initWidget()
{
    
    
	...
	m_customPlot = new QCustomPlot();
    m_customPlot = ui->customplot;
    setBarCustomPlot(m_customPlot,0);

    m_customPlot_2 = new QCustomPlot();
    m_customPlot_2 = ui->customplot_2;
    setBarCustomPlot(m_customPlot_2,1);
    ...

二、示例完整代码展示

这里将示例的完整代码进行展示,详情见代码注释
1.widget.h

#ifndef WIDGET_H
#define WIDGET_H

#include <QWidget>
#include "CustomPlot/qcustomplot.h"

QT_BEGIN_NAMESPACE
namespace Ui {
    
     class Widget; }
QT_END_NAMESPACE

class Widget : public QWidget
{
    
    
    Q_OBJECT

public:
    Widget(QWidget *parent = nullptr);
    ~Widget();

    void initWidget();
    void setBarCustomPlot(QCustomPlot *customPlot,int index);
    void setBarReplot(QCustomPlot *customPlot);

protected:
    bool eventFilter(QObject *watched,QEvent *event);

private slots:
    void on_pb_Start_clicked();
    void on_pb_Replot_clicked();
    void on_pb_Change_clicked();

private:
    Ui::Widget *ui;

    QCustomPlot *m_customPlot;
    QCustomPlot *m_customPlot_2;
    QCPItemText *maxLabel[2];
    QCPItemText *minLabel[2];

    int serialNum;
    double maxNum;
    double minNum;
    double xNum;
    double yNum;
};
#endif // WIDGET_H

2.widget.cpp

#include "widget.h"
#include "ui_widget.h"

Widget::Widget(QWidget *parent)
    : QWidget(parent)
    , ui(new Ui::Widget)
{
    
    
    ui->setupUi(this);
    this->initWidget();
}

Widget::~Widget()
{
    
    
    delete m_customPlot;
    delete ui;
}

void Widget::initWidget()
{
    
    
    //初始化变量
    serialNum = 0;
    maxNum = 0;
    minNum = 0;
    xNum = 0;
    yNum = 0;

    m_customPlot = new QCustomPlot();
    m_customPlot = ui->customplot;
    setBarCustomPlot(m_customPlot,0);

    m_customPlot_2 = new QCustomPlot();
    m_customPlot_2 = ui->customplot_2;
    setBarCustomPlot(m_customPlot_2,1);

    //添加事件过滤器
    ui->customplot->installEventFilter(this);
    ui->customplot_2->installEventFilter(this);
}

void Widget::setBarCustomPlot(QCustomPlot *customPlot,int index)
{
    
    
    //qDebug()<<"*customPlot:"<<customPlot->objectName();

    //设置背景黑色
    customPlot->axisRect()->setBackground(QBrush(Qt::black));

    //x轴设置
    customPlot->xAxis->setVisible(true);
    customPlot->xAxis->setTickLabels(false);
    customPlot->xAxis->setSubTickLength(0);
    customPlot->xAxis->setTickLength(0);
    customPlot->xAxis->setRange(0,30);

    //x2轴设置
    customPlot->xAxis2->setVisible(true);
    customPlot->xAxis2->setTickLabels(false);
    customPlot->xAxis2->setSubTickLength(0);
    customPlot->xAxis2->setTickLength(0);

    //y轴设置
    customPlot->yAxis->setVisible(true);
    customPlot->yAxis->setTickLabels(false);
    customPlot->yAxis->setSubTickLength(0);
    customPlot->yAxis->setTickLength(0);
    customPlot->yAxis->setRange(-1.6,1.6);
    customPlot->yAxis->ticker()->setTickCount(3);
    customPlot->yAxis->grid()->setPen(QPen(Qt::white));

    //y2轴设置
    customPlot->yAxis2->setVisible(true);
    customPlot->yAxis2->setTickLabels(false);
    customPlot->yAxis2->setSubTickLength(0);
    customPlot->yAxis2->setTickLength(0);

    //设置文本框
    maxLabel[index] = new QCPItemText(customPlot);   //在QCustomplot中新建文字框
    maxLabel[index]->position->setType(QCPItemPosition::ptAxisRectRatio);   //位置类型
    maxLabel[index]->position->setCoords(0.96,0.18);
    maxLabel[index]->setText("   ");
    maxLabel[index]->setColor(QColor(Qt::white));   //字体颜色
    maxLabel[index]->setFont(QFont(font().family(),8));   //字体大小
    maxLabel[index]->setBrush(QColor(Qt::red));
    maxLabel[index]->setPadding(QMargins(2,2,2,2));   //文字距离边框几个像素

    minLabel[index] = new QCPItemText(customPlot);
    minLabel[index]->position->setType(QCPItemPosition::ptAxisRectRatio);
    minLabel[index]->position->setCoords(0.96,0.82);
    minLabel[index]->setText("   ");
    minLabel[index]->setColor(QColor(Qt::white));
    minLabel[index]->setFont(QFont(font().family(),8));
    minLabel[index]->setBrush(QColor(Qt::red));
    minLabel[index]->setPadding(QMargins(2,2,2,2));

}

void Widget::setBarReplot(QCustomPlot *customPlot)
{
    
    
    QCPBars *bars = new QCPBars(customPlot->xAxis,customPlot->yAxis);
    bars->setAntialiased(false);   //为了更好的边框效果,关闭抗齿锯
    bars->setWidth(1);   //设置各柱之前无间隔
    bars->setPen(QPen(QColor(Qt::black).lighter(100)));   //设置柱状图的边框颜色
    qDebug()<<"maxNum:"<<maxNum<<"   minNum:"<<minNum;

    if((yNum>minNum*0.8)&&(yNum<maxNum*0.8))
    {
    
    
        bars->setBrush(QColor(Qt::green));//绿色
    }
    else if((yNum<minNum)||(yNum>maxNum))
    {
    
    
        bars->setBrush(QColor(Qt::red));//红色
    }
    else
    {
    
    
        bars->setBrush(QColor(Qt::yellow));//黄色
    }

    QVector<double> ticks1;
    ticks1 << xNum;
    QVector<double> fossilData1;
    fossilData1  << yNum;
    bars->setData(ticks1,fossilData1,true);

    if(xNum > 30)
    {
    
    
        customPlot->xAxis->setRange(xNum-29.5,xNum+0.5);
    }

    customPlot->replot(QCustomPlot::rpQueuedReplot);
}

bool Widget::eventFilter(QObject *watched, QEvent *event)
{
    
    
    if(event->type() == QEvent::MouseButtonDblClick)   //双击图表事件
    {
    
    
        if(watched == ui->customplot)
        {
    
    
            qDebug()<<"customplot doubleClicked";
        }
        else if(watched == ui->customplot_2)
        {
    
    
            qDebug()<<"customplot_2 doubleClicked";
        }
    }
    return QWidget::eventFilter(watched,event);
}

void Widget::on_pb_Start_clicked()
{
    
    
    //maxLabel[0]->setText("-1.11");
    //minLabel[0]->setText("-1.11");
    maxLabel[0]->setText(QString::number(maxNum,'f',2));
    minLabel[0]->setText(QString::number(minNum,'f',2));
    maxLabel[1]->setText(QString::number(maxNum,'f',2));
    minLabel[1]->setText(QString::number(minNum,'f',2));

    serialNum ++;
    qDebug()<<"serialNum:"<<serialNum;
    xNum = serialNum - 0.5;
    if(yNum < 1.5)
    {
    
    
        yNum += 0.1;
    }
    else
    {
    
    
        yNum = -1.5;
    }
    qDebug()<<"xNum:"<<xNum<<"   yNum:"<<yNum;

    setBarReplot(m_customPlot);
    setBarReplot(m_customPlot_2);
}

void Widget::on_pb_Replot_clicked()
{
    
    
    //清除数据
    serialNum = 0;
    maxNum = 0;
    minNum = 0;
    xNum = 0;
    yNum = 0;
    maxLabel[0]->setText("   ");
    minLabel[0]->setText("   ");
    maxLabel[1]->setText("   ");
    minLabel[1]->setText("   ");
    m_customPlot->xAxis->setRange(0,30);
    m_customPlot->clearPlottables();
    m_customPlot->replot(QCustomPlot::rpQueuedReplot);
    m_customPlot_2->xAxis->setRange(0,30);
    m_customPlot_2->clearPlottables();
    m_customPlot_2->replot(QCustomPlot::rpQueuedReplot);
}

void Widget::on_pb_Change_clicked()
{
    
    
    //设置文本框
    maxNum = 1.00;
    minNum = -1.00;
    maxLabel[0]->setText(QString::number(maxNum,'f',2));
    minLabel[0]->setText(QString::number(minNum,'f',2));
    maxLabel[1]->setText(QString::number(maxNum,'f',2));
    minLabel[1]->setText(QString::number(minNum,'f',2));
    m_customPlot->replot(QCustomPlot::rpQueuedReplot);
    m_customPlot_2->replot(QCustomPlot::rpQueuedReplot);
}

3.widget.ui见上文。


三、下载链接

我的示例百度网盘链接:https://pan.baidu.com/s/1IAHCmKt4x14oef_09kD0Gg
提取码:xxcj

总结

测试发现多个QCustomPlot同时显示也是很流畅的,不会造成界面卡顿啥的,文中实现界面动态显示的关键是这句代码customPlot->xAxis->setRange(xNum-29.5,xNum+0.5),大家可以根据实际进行图表X轴范围的修改。在实际工作中可能还会遇到点击QCustomPlot界面来实现其他的功能,这时候可以考虑使用事件过滤器的方法,文中进行了双击图表的事件重写,可以根据项目需要进行更改。

本系列文章上一篇:(三)Qt+QCustomPlot生成上下方向/不同颜色的条形图(柱形图)

hello:
共同学习,共同进步,如果还有相关问题,可在评论区留言进行讨论。

猜你喜欢

转载自blog.csdn.net/XCJandLL/article/details/127885968