qt之qcustomplot绘制曲线和柱状图快捷通用需求界面

一、前言

本来想在便捷的帖子中写,但是文章太长了,占用空间,所以想想还是单独分离出来,之后有新内容更新也会随时更新到这个帖子中来

二、环境

qt57

window10

三、正文

(1)绘制曲线----带光标回调数值功能----带点击曲线绑定回调函数弹出界面功能

pro文件加入QT+=printsupport

h文件加入

#include "CustomWidget/QCustomPlot/qcustomplot.h"
#include "CustomWidget/QCustomPlot/mytracer.h"

private slots:
    void QCustomPlot_page1_Updata(QCustomPlot *CustomPlot);
    void QCustomPlot_page1_Init(QCustomPlot *CustomPlot);
    void showTracer1(QMouseEvent *event);
    void selectionChanged();

private:
    QVector<double> x_vec_p1,x_p1;
    QSharedPointer<myTracer> m1_TracerY;

cpp文件加入

    主函数:
    QCustomPlot_page1_Init(ui->page1_widget1);//初始化QCustomPlot控件
    QCustomPlot_page1_Updata(ui->page1_widget1);

    其他函数:
//初始化主界面曲线
void Sysin::QCustomPlot_page1_Init(QCustomPlot *CustomPlot)
{
    CustomPlot->addGraph();
    CustomPlot->graph(0)->setPen(QPen("#55ff00"));//设置曲线颜色,对应ui界面的CheckBox颜色,修改注意同步修改
    CustomPlot->graph(0)->setName("DY板");
    CustomPlot->xAxis->setLabel("组数(T)");
    CustomPlot->yAxis->setLabel("当前值(V)");
    CustomPlot->yAxis->setRange(-5,5);//设置y轴范围
    QLinearGradient plotGradient;
    plotGradient.setStart(0, 0);
    plotGradient.setFinalStop(0, 350);
    plotGradient.setColorAt(0, QColor(42,63,22));
    plotGradient.setColorAt(1, QColor(0,0,0));
    CustomPlot->setBackground(plotGradient);      // 设置背景颜色
    QLinearGradient axisRectGradient;
    axisRectGradient.setStart(0, 0);
    axisRectGradient.setFinalStop(0, 350);
    axisRectGradient.setColorAt(0, QColor(42,63,22));
    axisRectGradient.setColorAt(1, QColor(0, 0, 0));
    CustomPlot->axisRect()->setBackground(axisRectGradient);   // 设置QCPAxisRect背景颜色
    CustomPlot->xAxis->setBasePen(QPen(Qt::white,4));//设置x轴坐标轴颜色
    CustomPlot->yAxis->setBasePen(QPen(Qt::white,4));//设置y轴坐标轴颜色
    CustomPlot->xAxis->setTickPen(QPen(Qt::white, 4));  // 轴刻度线的画笔
    CustomPlot->yAxis->setTickPen(QPen(Qt::white, 4));  // 轴刻度线的画笔
    CustomPlot->xAxis->setSubTickPen(QPen(Qt::white, 2)); // 轴子刻度线的画笔
    CustomPlot->yAxis->setSubTickPen(QPen(Qt::white, 2)); // 轴子刻度线的画笔
    CustomPlot->xAxis->setTickLabelColor(Qt::white);//设置x轴坐标颜色
    CustomPlot->yAxis->setTickLabelColor(Qt::white);//设置y轴坐标颜色
    CustomPlot->xAxis->setLabelColor(Qt::white);//设置x轴名称颜色
    CustomPlot->yAxis->setLabelColor(Qt::white);//设置y轴名称颜色
    CustomPlot->xAxis->setUpperEnding(QCPLineEnding::esSpikeArrow);  // 设置轴线结束时的风格为 实角三角形但内部有凹陷的形状, setLowerEnding设置轴线开始时的风格
    CustomPlot->yAxis->setUpperEnding(QCPLineEnding::esSpikeArrow);  // 设置轴线结束时的风格为 实角三角形但内部有凹陷的形状, setLowerEnding设置轴线开始时的风格
    // 每条网格对应一个刻度
    CustomPlot->xAxis->grid()->setPen(QPen(QColor(140, 140, 140), 1, Qt::DotLine));     // 网格线(对应刻度)画笔
    CustomPlot->yAxis->grid()->setPen(QPen(QColor(140, 140, 140), 1, Qt::DotLine));
    CustomPlot->xAxis->grid()->setSubGridPen(QPen(QColor(80, 80, 80), 1, Qt::DotLine)); // 子网格线(对应子刻度)画笔
    CustomPlot->yAxis->grid()->setSubGridPen(QPen(QColor(80, 80, 80), 1, Qt::DotLine));
    //CustomPlot->xAxis->grid()->setSubGridVisible(true);     // 显示子网格线
    //CustomPlot->yAxis->grid()->setSubGridVisible(true);
    CustomPlot->xAxis->grid()->setZeroLinePen(QPen(Qt::red));   // 设置刻度为0时的网格线的画笔
    CustomPlot->yAxis->grid()->setZeroLinePen(QPen(Qt::red));

    CustomPlot->legend->setBrush(QBrush(Qt::transparent));     //设置图例透明无边框
    CustomPlot->legend->setFont(QFont("sans", 16, QFont::Bold));
    CustomPlot->legend->setBorderPen(Qt::NoPen);
    CustomPlot->legend->setVisible(true);//设置曲线名称可见
    CustomPlot->legend->setTextColor(Qt::white);//black
    CustomPlot->setInteractions(QCP::iRangeDrag | QCP::iRangeZoom| QCP::iSelectAxes |
                                QCP::iSelectLegend | QCP::iSelectPlottables);//可以进行鼠标位置 放大缩小 拖拽  放大缩小坐标系!!!功能非常强大
    CustomPlot->legend->setSelectableParts(QCPLegend::spItems);
    connect(CustomPlot, SIGNAL(selectionChangedByUser()), this, SLOT(selectionChanged()));

    //CustomPlot->setInteractions(QCP::iRangeDrag | QCP::iRangeZoom);//可以进行鼠标位置 放大缩小 拖拽  放大缩小坐标系!!!功能非常强大
    m1_TracerY = QSharedPointer<myTracer> (new myTracer(CustomPlot, CustomPlot->graph(0), DataTracer));
    connect(CustomPlot, SIGNAL(mouseMove(QMouseEvent*)), this,SLOT(showTracer1(QMouseEvent*)));
}
void Sysin::selectionChanged()
{

      QCPGraph *graph = ui->page1_widget1->graph(0);
      QCPPlottableLegendItem *item = ui->page1_widget1->legend->itemWithPlottable(graph);
      if (item->selected()/*||graph->selected()*/){
item->setSelected(false);//马上取消选择
        QColorDialog *m_pColor = new QColorDialog(this);
        m_pColor->setWindowModality(Qt::ApplicationModal);
        m_pColor->setCurrentColor(QColor(Qt::red));//初始颜色
        m_pColor->show();
        //m_pColor->move(720,200);
//        connect(m_pColor,SIGNAL(currentColorChanged(QColor)),this,SLOT(ShowColor(QColor)));//显示当前选中颜色的效果
//        connect(m_pColor,SIGNAL(colorSelected(QColor)),this,SLOT(SetColor(QColor)));//OK信号连接
      }

}
//曲线鼠标回调显示坐标值
void Sysin::showTracer1(QMouseEvent *event)
{
    double x = ui->page1_widget1->xAxis->pixelToCoord(event->pos().x());
    double y = 0;
    QSharedPointer<QCPGraphDataContainer> tmpContainer;
    tmpContainer = ui->page1_widget1->graph(0)->data();
    //使用二分法快速查找所在点数据!!!敲黑板,下边这段是重点
    int low = 0, high = tmpContainer->size();
    while(high > low){
       int middle = (low + high) / 2;
       if(x < tmpContainer->constBegin()->mainKey() ||
               x > (tmpContainer->constEnd()-1)->mainKey())
           break;

       if(x == (tmpContainer->constBegin() + middle)->mainKey()){
           y = (tmpContainer->constBegin() + middle)->mainValue();
           break;
       }
       if(x > (tmpContainer->constBegin() + middle)->mainKey()){
           low = middle;
       }
       else if(x < (tmpContainer->constBegin() + middle)->mainKey()){
           high = middle;
       }
       if(high - low <= 1){   //差值计算所在位置数据
           y = (tmpContainer->constBegin()+low)->mainValue() + ( (x - (tmpContainer->constBegin() + low)->mainKey()) *
               ((tmpContainer->constBegin()+high)->mainValue() - (tmpContainer->constBegin()+low)->mainValue()) ) /
               ((tmpContainer->constBegin()+high)->mainKey() - (tmpContainer->constBegin()+low)->mainKey());
           break;
       }
    }
    m1_TracerY->updatePosition(x, y,true);
    m1_TracerY->setText(QString::number(x, 'f', 0),QString::number(y, 'f', 1));//x轴取整数,y轴保留两位小数

    ui->page1_widget1->replot();
}
//更新主界面曲线函数
void Sysin::QCustomPlot_page1_Updata(QCustomPlot *CustomPlot)
{
    for(int j=0;j<700;j++){//这时容器里面还没200个点 所有一直向里面存
        if(j<50)
            x_vec_p1.append((double)(qrand()%10)/100+0.2);
        else if(j>150)
            x_vec_p1.append((double)(qrand()%10)/100+0.3);
        else
            x_vec_p1.append((double)(qrand()%10)/40+1.9);
        x_p1.append(j);
        CustomPlot->xAxis->setRange(0,700);//设置范围正好 能显示当前点
    }
    //CustomPlot->yAxis->rescale(true);//设置Y轴坐标系 自动缩放以正常显示所有的数据
    //CustomPlot->graph(0)->setVisible(true);
    CustomPlot->graph(0)->setData(x_p1,x_vec_p1);//设置数据

    CustomPlot->replot();//重绘制
}

ui文件加入widget控件提升类CustomWidget/QCustomPlot/qcustomplot.h

引用文件加入QCustomplot曲线带回调光标

执行效果

(2)绘制柱状图------带双个柱状------带柱状数值显示

需要重写Qcustomplot的QCPBars类的draw函数,正常是不需要的,但是用到了柱状数值,所以就用重写类的方式

pro文件加入QT+=printsupport

h文件

#include "CustomWidget/QCustomPlot/qcustomplot.h"
#include "CustomWidget/QCustomPlot/CustomBars.h"

cpp文件

    CustomBars *nuclear = new CustomBars(ui->page1_widget1->xAxis, ui->page1_widget1->yAxis);
    CustomBars *fossil = new CustomBars(ui->page1_widget1->xAxis, ui->page1_widget1->yAxis);
    nuclear->setSpacing(25);//设置间隔
    fossil->setSpacing(5);//设置间隔
    nuclear->setFont(QFont(QLatin1String("SimSun"), 14 ,true));//设置字体
    fossil->setFont(QFont(QLatin1String("SimSun"), 14 ,false));//设置字体


    // 设置背景颜色
    QLinearGradient plotGradient;
    plotGradient.setStart(0, 0);
    plotGradient.setFinalStop(0, 350);
    plotGradient.setColorAt(0, QColor(42,63,22));
    plotGradient.setColorAt(1, QColor(0,0,0));
    ui->page1_widget1->setBackground(plotGradient);

    nuclear->setAntialiased(false);//取消反锯齿
    fossil->setAntialiased(false);//取消反锯齿
    nuclear->setStackingGap(1);//设置与下方柱子的像素点间隔
    fossil->setStackingGap(1);//设置与下方柱子的像素点间隔
    // set names and colors: 设置名字和颜色
    fossil->setName("正常");
    fossil->setPen(QPen(QColor(75, 121, 2).lighter(170)));// >100 则返回较浅的颜色
    fossil->setBrush(QColor(75, 121, 2));
    nuclear->setName("异常");
    nuclear->setPen(QPen(QColor(191, 23, 43).lighter(150)));
    nuclear->setBrush(QColor(191, 23, 43));
    nuclear->moveAbove(fossil);// stack bars on top of each other://移动bar到其他bar上方

    // prepare x axis with country labels: //设置x轴标签
    QVector<double> ticks;
    QVector<QString> labels;
    ticks << 1 << 2 << 3 << 4 << 5<< 6;
    labels << "总数" << "待一" << "待二" << "废品" << "废品" << "废品";
    QSharedPointer<QCPAxisTickerText> textTicker(new QCPAxisTickerText);
    textTicker->addTicks(ticks, labels);
    ui->page1_widget1->xAxis->setTicker(textTicker);
    ui->page1_widget1->xAxis->setTickLabelRotation(60);//设置标签角度旋转60度
    ui->page1_widget1->xAxis->setSubTicks(false);//设置是否显示子标签
    ui->page1_widget1->xAxis->setTickLength(0, 4);
    ui->page1_widget1->xAxis->setRange(0, 7);//设置x轴区间
    ui->page1_widget1->xAxis->setBasePen(QPen(Qt::white));
    ui->page1_widget1->xAxis->setTickPen(QPen(Qt::white));
    ui->page1_widget1->xAxis->grid()->setVisible(true);//设置网格是否显示
    ui->page1_widget1->xAxis->grid()->setPen(QPen(QColor(130, 130, 130), 0, Qt::DotLine));
    ui->page1_widget1->xAxis->setTickLabelColor(Qt::white);//设置标记标签颜色
    ui->page1_widget1->xAxis->setLabelColor(Qt::white);

    // prepare y axis: //设置y轴
    ui->page1_widget1->yAxis->setRange(0, 60);
    ui->page1_widget1->yAxis->setPadding(5); // a bit more space to the left border 设置左边留空间
    ui->page1_widget1->yAxis->setLabel("总数量");
    ui->page1_widget1->yAxis->setBasePen(QPen(Qt::white));
    ui->page1_widget1->yAxis->setTickPen(QPen(Qt::white));
    ui->page1_widget1->yAxis->setSubTickPen(QPen(Qt::white));//设置SubTick颜色,SubTick指的是轴上的
    //刻度线
    ui->page1_widget1->yAxis->grid()->setSubGridVisible(false);//刻度线不可见
    ui->page1_widget1->yAxis->setTickLabelColor(Qt::white);//设置标记标签颜色(y轴标记标签)
    ui->page1_widget1->yAxis->setLabelColor(Qt::white);//设置标签颜色(y轴右边标签)
    ui->page1_widget1->yAxis->grid()->setPen(QPen(QColor(130, 130, 130), 0, Qt::SolidLine));
    ui->page1_widget1->yAxis->grid()->setSubGridPen(QPen(QColor(130, 130, 130), 0, Qt::DotLine));

    // Add data:添加数据
    QVector<double> fossilData,nuclearData;
    fossilData  << 5<< 10 << 15 << 20 << 0 << 0 ;
    nuclearData << 5 << 5 << 25 << 0 << 20 << 10;
    fossil->setData(ticks, fossilData);
    nuclear->setData(ticks, nuclearData);

    // setup legend: 设置标签
    ui->page1_widget1->legend->setVisible(true);
    ui->page1_widget1->axisRect()->insetLayout()->setInsetAlignment(0, Qt::AlignTop|Qt::AlignRight);
    ui->page1_widget1->legend->setBrush(QColor(255, 255, 255, 100));
    ui->page1_widget1->legend->setBorderPen(Qt::NoPen);
    QFont legendFont = font();
    legendFont.setPointSize(10);
    ui->page1_widget1->legend->setFont(legendFont);
    ui->page1_widget1->setInteractions(QCP::iRangeDrag | QCP::iRangeZoom);//设置 可拖动,可放大缩小

ui文件加入widget控件提升类CustomWidget/QCustomPlot/qcustomplot.h

引用文件加入QCustomplot柱状图带数值,其中CustomBars为重写的类,调用下载文件即可

执行效果

四、结语

未完待续。。。

猜你喜欢

转载自blog.csdn.net/qq_37603131/article/details/113153798
今日推荐