首页 > 其他分享 >QCustomPlot使用

QCustomPlot使用

时间:2024-04-07 10:33:44浏览次数:27  
标签:plot const double void QCustomPlot range xAxis 使用

QCustomPlot用法及源代码
放大缩小、动态增加数据、
鼠标拖拽矩形框选曲线数据(T1~T2时间段内的数据)
鼠标点击显示数据点
x缩放、y缩放、还原、截图等功能
通用创建文件夹功能;
通用MessageBox,对QMessageBox进行重写

在这里插入图片描述

在这里插入图片描述

在这里插入图片描述

源码如下

CustomPlotEx.h

#pragma once

#include <QWidget>
#include "qcustomplot.h"
#include "IntToString.h"

class CustomPlotEx :public QCustomPlot
{
    Q_OBJECT
public:
    CustomPlotEx(QWidget* parent);
    ~CustomPlotEx();

    enum ActionEnum
    {
        Action_X,
        Action_Y,
        Action_T1,
        Action_T2,
        Action_Count
    };
    Q_ENUM(ActionEnum)

    void init();
    void setData(const QVector<double> &keys, const QVector<double> &values, bool alreadySorted = false);
    void set_yAxis_name(const QString& name);
    void set_xAxis_name(const QString& name);
    void set_yAxis_range(double lower, double upper);
    void set_xAxis_range(double lower, double upper);
    void set_xAxis_range(double position, double size, Qt::AlignmentFlag alignment);
    void get_xAxis_range(double &lower, double &upper);
    void set_yAxis_rescale();
    void setGridVisible(bool isVisible);
    void setSelectRectEnable(bool enable) { m_enableSelectRect = enable; }
    void setMenuEnable(bool enable) { m_enableMenu = enable; }
    void set_xAxisSubGridVisible(bool isVisible);

signals:
    void signal_selection_xAxis_range(const double lower, const double upper);
    void signal_menu_select_time(const int type, const float value);
    void SigDataSelectedToSend(QVector<double>keys, QVector<double>values);
protected:
    virtual void mousePressEvent(QMouseEvent *event);
    virtual void mouseMoveEvent(QMouseEvent *event);
    virtual void mouseReleaseEvent(QMouseEvent *event);
private:
    void setTickOutward();
    void setTickerTick();
    void setGrid();
    void initSelectRect();
    void selectRectEnd();
    void selectRectStart(QMouseEvent *event);
    void selectRectDraw(QMouseEvent *event);
    void initMenu();
    void showMenu(QMouseEvent *event);
    bool verifyRange(const double xValue, const double yValue);
    void initLanguage();
    void setWidgetActionText(QWidgetAction *widgetAction, const QString& text);
    QString getWidgetActionText(QWidgetAction *widgetAction);
private slots:
	void slot_menuTriggered(QAction* action);

private:
    QRubberBand *m_rubberBand = NULL;
    QPoint m_startPos;
	bool m_enableSelectRect = false;
    QMenu* m_menu = nullptr;
    bool m_enableMenu = false;
    bool m_isMouseMoved = false;
    static EnumToString m_szActionName[];

};


CustomPlotEx.cpp

#include "CustomPlotEx.h"
#include "Language.h"
#include "MenuActionWdt.h"

EnumToString CustomPlotEx::m_szActionName[] =
{
    { Action_T1, Trans("x选为T1") },
    { Action_T2, Trans("x选为T2") },
    { Action_X, Trans("x:") },
    { Action_Y, Trans("y:") },
};

CustomPlotEx::CustomPlotEx(QWidget* parent) :QCustomPlot(parent)
{
	qRegisterMetaType<QVector<double>>("QVector<double>");
}
CustomPlotEx::~CustomPlotEx()
{
}
void CustomPlotEx::initLanguage()
{
    static bool init = false;
    if (!init)
    {
        Lang.translate(m_szActionName, Action_Count);
        init = true;
    }
}

void CustomPlotEx::init()
{
    initLanguage();
    addGraph();//添加一条曲线
    graph(0)->setPen(QPen(Qt::blue));//设置画笔
    //setTimeTicker();

    xAxis->setLabel(Trans("时间(s)"));
    yAxis->setLabel(Trans("电流(pA)"));
    xAxis->setRange(0, 10);
    yAxis->setRange(-1000, 1000);

    setTickerTick();
    setTickOutward();
    setGrid();


    //  QCPTextElement* textElement = new QCPTextElement(m_plot, Trans("电流(pA)"));
    //  m_plot->plotLayout()->insertRow(0);
    //  m_plot->plotLayout()->addElement(0, 0, textElement);

    setBackground(QBrush(qRgb(226, 241, 250)));
    axisRect()->setBackground(QBrush(Qt::gray));

    //  xAxis->setNumberFormat("f");//g灵活的格式,b漂亮的指数形式,c乘号改成×
    //  xAxis->setNumberPrecision(2);//精度2

    initSelectRect();
    initMenu();
}

void CustomPlotEx::set_yAxis_name(const QString& name)
{
    yAxis->setLabel(name);
    replot();
}

void CustomPlotEx::setTickOutward()
{
    xAxis->setTickLength(0, 8);
    xAxis->setSubTickLength(0, 5);

    yAxis->setTickLength(0, 8);
    yAxis->setSubTickLength(0, 5);
}

void CustomPlotEx::setGrid()
{
    setGridVisible(true);
    yAxis->grid()->setZeroLinePen(QPen(Qt::white));//y轴0线颜色白色
    xAxis->grid()->setSubGridVisible(false);
    set_xAxisSubGridVisible(false);
}

void CustomPlotEx::set_xAxisSubGridVisible(bool isVisible)
{
    xAxis->grid()->setSubGridVisible(isVisible);
}

void CustomPlotEx::setGridVisible(bool isVisible)
{
    //yAxis->grid()->setSubGridVisible(isVisible);
    xAxis->grid()->setVisible(isVisible);
    yAxis->grid()->setVisible(isVisible);
    replot();
}

void CustomPlotEx::setTickerTick()
{
    yAxis->ticker()->setTickCount(11);//11个主刻度
    yAxis->ticker()->setTickStepStrategy(QCPAxisTicker::tssReadability);//可读性优于设置
    xAxis->ticker()->setTickCount(6);
    xAxis->ticker()->setTickStepStrategy(QCPAxisTicker::tssReadability);//可读性优于设置
}

void CustomPlotEx::setData(const QVector<double> &keys, const QVector<double> &values, bool alreadySorted/* = false*/)
{
    graph(0)->setData(keys, values, alreadySorted);
}

void CustomPlotEx::set_yAxis_range(double lower, double upper)
{
    yAxis->setRange(lower, upper);
}

void CustomPlotEx::set_xAxis_range(double lower, double upper)
{
    xAxis->setRange(lower, upper);
}

void CustomPlotEx::set_xAxis_range(double position, double size, Qt::AlignmentFlag alignment)
{
    xAxis->setRange(position, size, alignment);
}

void CustomPlotEx::get_xAxis_range(double &lower, double &upper)
{
    lower = xAxis->range().lower;
    upper = xAxis->range().upper;
}

void CustomPlotEx::set_yAxis_rescale()
{
    graph(0)->rescaleValueAxis(false, true);
}

void CustomPlotEx::initSelectRect()
{
    m_rubberBand = new QRubberBand(QRubberBand::Rectangle, this);
}

void CustomPlotEx::mousePressEvent(QMouseEvent *event)
{
    QCustomPlot::mousePressEvent(event);

    if (event->buttons() & Qt::LeftButton)
    {
        selectRectStart(event);
    }
}

void CustomPlotEx::selectRectStart(QMouseEvent *event)
{
    if (!m_enableSelectRect)
        return;

    m_startPos = event->pos();
    m_rubberBand->resize(0, 0);
    m_rubberBand->show();
}

void CustomPlotEx::mouseMoveEvent(QMouseEvent *event)
{
    if (event->buttons() & Qt::LeftButton)
    {
        selectRectDraw(event);
        return;
    }

    if (event->buttons() & Qt::RightButton)
    {
        m_isMouseMoved = true;
    }

    QCustomPlot::mouseMoveEvent(event);
}

void CustomPlotEx::selectRectDraw(QMouseEvent *event)
{
    if (!m_enableSelectRect)
        return;

    QRect normalRect = QRect(m_startPos, event->pos()).normalized();//任意两点定义矩形
    m_rubberBand->setGeometry(normalRect);
}

void CustomPlotEx::mouseReleaseEvent(QMouseEvent *event)
{
    QCustomPlot::mouseReleaseEvent(event);

    if (event->button() == Qt::LeftButton)
    {
        selectRectEnd();
    }
    else if (event->button() == Qt::RightButton)
    {
        showMenu(event);
    }
}

void CustomPlotEx::showMenu(QMouseEvent *event)
{
    if (!m_enableMenu)
        return;

    if (m_isMouseMoved)
    {
        m_isMouseMoved = false;
        return;
    }
    
    double xValue = xAxis->pixelToCoord(event->pos().x());
    double yValue = yAxis->pixelToCoord(event->pos().y());

    if (!verifyRange(xValue, yValue))
    {
        return;
    }

    QList<QAction*> listAction = m_menu->actions();
    setWidgetActionText((QWidgetAction*)listAction[Action_X], QString::number(xValue));
    setWidgetActionText((QWidgetAction*)listAction[Action_Y], QString::number(yValue));
    m_menu->exec(QCursor::pos());
}

void CustomPlotEx::setWidgetActionText(QWidgetAction *widgetAction, const QString& text)
{
    MenuActionWdt* wdt = (MenuActionWdt*)widgetAction->defaultWidget();
    wdt->setLineEditText(text);
}

bool CustomPlotEx::verifyRange(const double xValue, const double yValue)
{
    if (xValue < xAxis->range().lower || xValue > xAxis->range().upper)
    {
        return false;
    }

    if (yValue < yAxis->range().lower || yValue > yAxis->range().upper)
    {
        return false;
    }

    return true;
}

void CustomPlotEx::selectRectEnd()
{
    if (!m_enableSelectRect)
        return;

    m_rubberBand->hide();
    QRect normalRect = m_rubberBand->geometry();
    if (normalRect.width() == 0 || normalRect.height() == 0)
    {
        return;
    }

    double xLower = xAxis->pixelToCoord(normalRect.left());
    double xUpper = xAxis->pixelToCoord(normalRect.right());
    this->xAxis->setRange(xLower, xUpper);
    this->yAxis->setRange(yAxis->pixelToCoord(normalRect.bottom()), yAxis->pixelToCoord(normalRect.top()));
    this->replot();//立即刷新图像

    emit signal_selection_xAxis_range(xLower, xUpper);

    //     鼠标框选数据
    QVector<double> keys;
    QVector<double> values;
	
    QCPRange x_range = this->xAxis->range();            //获取选中的当前可见范围
    QSharedPointer<QCPGraphDataContainer> dataContainter = this->graph(0)->data();
	QCPDataContainer<QCPGraphData>::const_iterator i;
	//以选中的当前可见范围进行处理
	for (i = dataContainter->findEnd(x_range.lower); i != dataContainter->findBegin(x_range.upper); i++)
	{
        auto key = i->key;
		auto value = i->value;
        keys.append(key);       
        values.append(value);    
	}
    emit SigDataSelectedToSend(keys, values);	
}

void CustomPlotEx::set_xAxis_name(const QString& name)
{
    xAxis->setLabel(name);
}

void CustomPlotEx::initMenu()
{
    m_menu = new QMenu(this);
    connect(m_menu, SIGNAL(triggered(QAction*)), this, SLOT(slot_menuTriggered(QAction*)));

    QMetaEnum metaEnum = QMetaEnum::fromType<CustomPlotEx::ActionEnum>();
    for (int i = 0; i < Action_Count; i++)
    {
        QString actionText = IntToString::string(m_szActionName, Action_Count, i);
        if (i <= Action_Y)
        {
            MenuActionWdt *view = new MenuActionWdt(this);
            view->setLabelText(actionText);
            QWidgetAction *widgetAction = new QWidgetAction(m_menu);
            widgetAction->setDefaultWidget(view);
            widgetAction->setObjectName(metaEnum.valueToKey(i));
            m_menu->addAction(widgetAction);
        }
        else
        {
            QAction* action = new QAction(actionText, this);
            action->setObjectName(metaEnum.valueToKey(i));
            m_menu->addAction(action);
        }
        
    }
}

void CustomPlotEx::slot_menuTriggered(QAction* action)
{
    QMetaEnum metaEnum = QMetaEnum::fromType<CustomPlotEx::ActionEnum>();
    int actionType = metaEnum.keysToValue(action->objectName().toLocal8Bit());
    if (actionType <= Action_Y)
    {
        return;
        MessageBoxCustom::information(Trans("数据下发次数类型不匹配,请输入整数!!!"));
    }

    QList<QAction*> listAction = m_menu->actions();
    QString value = getWidgetActionText((QWidgetAction*)listAction[Action_X]);

    emit signal_menu_select_time(actionType, value.toFloat());
}

QString CustomPlotEx::getWidgetActionText(QWidgetAction *widgetAction)
{
    MenuActionWdt* wdt = (MenuActionWdt*)widgetAction->defaultWidget();
    return wdt->getLineEditText();
}

CustomPlotWdt.h

#pragma once

#include "WidgetEx.h"
#include "CustomPlotEx.h"
#include "IntToString.h"

class CustomPlotWdt : public WidgetEx
{
    Q_OBJECT
public:
    CustomPlotWdt(QWidget* parent);
    ~CustomPlotWdt();

    enum BtnEnum
    {
        BTN_AXIS_SCALE,
        BTN_X_AXIS_SCALE,
        BTN_Y_AXIS_SCALE,
        BTN_AXIS_RESTORE,
        BTN_GRID_VISIBLE,
        BTN_SAVE_IMAGE,
        BTN_COUNT
    };
    Q_ENUM(BtnEnum)

    void init();
    void setData(const QVector<double> &keys, const QVector<double> &values, bool alreadySorted = false) { m_plot->setData(keys, values, alreadySorted); }
    void set_yAxis_name(const QString& name) { m_plot->set_yAxis_name(name); }
    void set_xAxis_name(const QString& name) { m_plot->set_xAxis_name(name); }
    void set_yAxis_range(double lower, double upper) { m_plot->set_yAxis_range(lower, upper); }
    void reset_yAxis_range();

    void set_xAxis_range(double lower, double upper);
    void get_xAxis_range(double &lower, double &upper) { m_plot->get_xAxis_range(lower, upper); }
    void set_yAxis_rescale() { m_plot->set_yAxis_rescale(); }
    void rescaleAxes();

    void setAxesRescale(bool isRescale) { m_isAxesRescale = true; }

    void replot(QCustomPlot::RefreshPriority refreshPriority = QCustomPlot::rpRefreshHint) { m_plot->replot(refreshPriority); }
    void set_xAxis_range(double position, double size, Qt::AlignmentFlag alignment) { m_plot->set_xAxis_range(position, size, alignment); }
    void setSelectRectEnable(bool enable) { m_plot->setSelectRectEnable(enable); }
    void setMenuEnable(bool enable) { m_plot->setMenuEnable(enable); }
    void setGridVisible(bool isVisible);
    void set_xAxisSubGridVisible(bool isVisible) { m_plot->set_xAxisSubGridVisible(isVisible); }
    
    void setTickerTextUpper(const double upper);
    void updateTickerText(const double lowerText, const double upperText);
    //void setTracer(const double key, const QColor& color, const int size);
    void setLine(const double key, const QColor& color, const int size);
    void hideLine() { m_straightLine->setVisible(false); }
    void resetTicker();
signals:
    void signal_selection_xAxis_range(const double lower, const double upper);
	void SigDataSelectedToSend(QVector<double>keys, QVector<double>values);
    void signal_timeSelect_T1(const float t);
    void signal_timeSelect_T2(const float t);
private slots:
    void slot_btnClicked();
    void slot_menu_select_time(const int type, const float value);
private:
    void initBtn();
    void initPlot();
    void initLayout();

    void setGridVisible();
    void setAxisScale(int btnType);
    void saveImage();
    void axisRestore();
    void reset_xAxis_range();
    
    void initLanguage();
    void initTracer();
    void initLine();
    
    void setAxis();
    void set_xAxis_UpperTextVisible();
private:
    static EnumToString m_szOperateName[];
    QList<QPushButton*> m_listBtn;

    CustomPlotEx* m_plot;
    bool m_isGridVisible = true;
    bool m_isAxesRescale = false;

    QCPRange m_xRange;
    QCPRange m_yRange;

    QCPItemTracer* m_tracer = NULL;
    QCPItemStraightLine* m_straightLine = NULL;

    double m_tickerTextUpper = 0;
    QSharedPointer<QCPAxisTicker> m_ticker;

    QCPRange m_originXRange;
};

CustomPlotWdt.cpp

#include "CustomPlotWdt.h"
#include "FileRelevance.h"
#include "MessageBoxCustom.h"
#include "Language.h"

EnumToString CustomPlotWdt::m_szOperateName[] =
{
    { BTN_AXIS_RESTORE, Trans("还原") },
    { BTN_AXIS_SCALE, Trans("缩放") },
    { BTN_X_AXIS_SCALE, Trans("x缩放") },
    { BTN_Y_AXIS_SCALE, Trans("y缩放") },
    { BTN_GRID_VISIBLE, Trans("网格") },
    { BTN_SAVE_IMAGE, Trans("截图") }
};

CustomPlotWdt::CustomPlotWdt(QWidget* parent)
    :WidgetEx(parent)
{
    initLanguage();
}


CustomPlotWdt::~CustomPlotWdt()
{
}

void CustomPlotWdt::initLanguage()
{
    static bool init = false;
    if (!init)
    {
        Lang.translate(m_szOperateName, BTN_COUNT);
        init = true;
    }
}

void CustomPlotWdt::initBtn()
{
    QMetaEnum metaEnum = QMetaEnum::fromType<CustomPlotWdt::BtnEnum>();
    for (int i = 0; i < BTN_COUNT; i++)
    {
        QPushButton *btn = new QPushButton(this);
        btn->setObjectName(metaEnum.valueToKey(i));
        btn->setText(IntToString::string(m_szOperateName, BTN_COUNT, i));
        connect(btn, &QPushButton::clicked, this, &CustomPlotWdt::slot_btnClicked);
        m_listBtn.append(btn);

        if (i <= BTN_Y_AXIS_SCALE)
        {
            btn->setCheckable(true);
        }
    }

    m_listBtn[BTN_AXIS_SCALE]->click();
}

void CustomPlotWdt::slot_btnClicked()
{
    QPushButton* btn = (QPushButton*)sender();
    QMetaEnum metaEnum = QMetaEnum::fromType<CustomPlotWdt::BtnEnum>();
    int btnType = metaEnum.keysToValue(btn->objectName().toLocal8Bit());

    if (btnType <= BTN_Y_AXIS_SCALE)
    {
        setAxisScale(btnType);
        return;
    }

    switch (btnType)
    {
    case BTN_AXIS_RESTORE:
        axisRestore();
        break;
    case BTN_GRID_VISIBLE:
        setGridVisible();
        break;
    case BTN_SAVE_IMAGE:
        saveImage();
        break;
    default:
        break;
    }
}

void CustomPlotWdt::axisRestore()
{
    if (m_isAxesRescale)
    {
        m_plot->set_xAxis_range(m_xRange.lower, m_xRange.upper);
        m_plot->set_yAxis_range(m_yRange.lower, m_yRange.upper);
    }
    else
    {
        reset_yAxis_range();
        reset_xAxis_range();
        //m_plot->xAxis->rescale(true);
    }
    
    m_plot->replot();
}

void CustomPlotWdt::reset_yAxis_range()
{
    m_plot->set_yAxis_range(-3000, 3000);
}

void CustomPlotWdt::saveImage()
{
    QString fileDir = QCoreApplication::applicationDirPath() + "/images/";
    FileRelevance::makeDirectory(fileDir);

    QDateTime dateTime = QDateTime::currentDateTime();
    QString fileName = fileDir + dateTime.toString("yyyyMMdd_hhmmss") + ".png";
    m_plot->savePng(fileName);
    MessageBoxCustom::information(Trans("截图成功!"));
}

void CustomPlotWdt::setGridVisible()
{
    setGridVisible(!m_isGridVisible);
}

void CustomPlotWdt::setGridVisible(bool isVisible)
{
    m_isGridVisible = isVisible;
    m_plot->setGridVisible(isVisible);
}

void CustomPlotWdt::setAxisScale(int btnType)
{
    for (int i = 0; i <= BTN_Y_AXIS_SCALE; i++)
    {
        m_listBtn[i]->setChecked(i == btnType);
    }

    switch (btnType)
    {
    case BTN_AXIS_SCALE:
        m_plot->axisRect()->setRangeZoom(Qt::Vertical | Qt::Horizontal);
        break;
    case BTN_X_AXIS_SCALE:
        m_plot->axisRect()->setRangeZoom(Qt::Horizontal);
        break;
    case BTN_Y_AXIS_SCALE:
        m_plot->axisRect()->setRangeZoom(Qt::Vertical);
        break;
    default:
        break;
    }
}

void CustomPlotWdt::init()
{
    initPlot();
    initBtn();
    initLayout();
    //initTracer();
    initLine();
}

void CustomPlotWdt::initPlot()
{
    m_plot = new CustomPlotEx(this);
    m_plot->init();
    m_plot->setInteractions(QCP::iRangeDrag | QCP::iRangeZoom);
    reset_yAxis_range();
    m_ticker = m_plot->xAxis->ticker();
    setAxis();
    //     m_plot->axisRect()->setRangeZoomFactor(1.1);
    //     m_plot->axisRect()->setRangeZoom(Qt::Vertical);

    connect(m_plot, &CustomPlotEx::signal_selection_xAxis_range, this, &CustomPlotWdt::signal_selection_xAxis_range);
	connect(m_plot, &CustomPlotEx::SigDataSelectedToSend, this, &CustomPlotWdt::SigDataSelectedToSend);
    connect(m_plot, &CustomPlotEx::signal_menu_select_time, this, &CustomPlotWdt::slot_menu_select_time);
}

void CustomPlotWdt::initLayout()
{
    const int btnWidth = 50;
    QVBoxLayout* rightLayout = new QVBoxLayout();
    for (int i = 0; i < BTN_COUNT; i++)
    {
        m_listBtn[i]->setFixedSize(btnWidth, btnWidth);
        rightLayout->addWidget(m_listBtn[i]);
    }
    rightLayout->addStretch();

    QHBoxLayout* mainLayout = new QHBoxLayout();
    mainLayout->addWidget(m_plot);
    mainLayout->addLayout(rightLayout);
    setLayout(mainLayout);
}

void CustomPlotWdt::rescaleAxes()
{
    m_plot->graph(0)->rescaleAxes();

    m_xRange = m_plot->xAxis->range();
    m_yRange = m_plot->yAxis->range();
}

void CustomPlotWdt::slot_menu_select_time(const int type, const float value)
{
    if (type == CustomPlotEx::Action_T1)
    {
        emit signal_timeSelect_T1(value);
    }
    else
        emit signal_timeSelect_T2(value);
}

void CustomPlotWdt::initTracer()
{
    m_tracer = new QCPItemTracer(m_plot);
    m_tracer->setGraph(m_plot->graph(0));
    m_tracer->setInterpolating(true);
    m_tracer->setStyle(QCPItemTracer::tsCircle);
    m_tracer->setVisible(false);
}

void CustomPlotWdt::initLine()
{
    m_straightLine = new QCPItemStraightLine(m_plot);
    m_straightLine->setClipToAxisRect(true);
    m_straightLine->point1->setCoords(0, 0);
    m_straightLine->point2->setCoords(0, 0);
}

// void CustomPlotWdt::setTracer(const double key, const QColor& color, const int size)
// {
//     QCPItemTracer* tracer = new QCPItemTracer(m_plot);
//     m_tracer->setGraphKey(key);
//     m_tracer->setPen(QPen(color));
//     m_tracer->setBrush(color);
//     m_tracer->setSize(size);
//     m_tracer->setVisible(true);
// }

void CustomPlotWdt::setLine(const double key, const QColor& color, const int size)
{
    QPen linesPen(color, size, Qt::SolidLine);
    m_straightLine->setPen(linesPen);
    m_straightLine->point1->setCoords(key, m_plot->yAxis->range().lower);
    m_straightLine->point2->setCoords(key, m_plot->yAxis->range().upper);
    m_straightLine->setVisible(true);
}

void CustomPlotWdt::setTickerTextUpper(const double upper)
{
    m_tickerTextUpper = upper;
}

void CustomPlotWdt::updateTickerText(const double lowerText, const double upperText)
{
    QMap<double, QString> showTicks;
    //showTicks.insert(0, QString::number(lowerText, 'f', 1));
    double showStepText = (upperText - lowerText) / 10;
    double realStepText = m_tickerTextUpper / 10;
    for (int i = 0; i <= 10; i++)
    {
        showTicks.insert(i*realStepText, QString::number(i*showStepText+lowerText, 'f', 1));
    }
    //showTicks.insert(m_tickerTextUpper, QString::number(upperText, 'f', 1));

    QSharedPointer<QCPAxisTickerText> textTicker(new QCPAxisTickerText);
    //textTicker->setSubTickCount(9);
    textTicker->addTicks(showTicks);
    m_plot->xAxis->setTicker(textTicker);
}

void CustomPlotWdt::resetTicker()
{
    m_plot->xAxis->setTicker(m_ticker);
}

void CustomPlotWdt::set_xAxis_range(double lower, double upper)
{
    m_plot->set_xAxis_range(lower, upper);
    m_originXRange = m_plot->xAxis->range();
}

void CustomPlotWdt::reset_xAxis_range()
{
    m_plot->set_xAxis_range(m_originXRange.lower, m_originXRange.upper);
}

void CustomPlotWdt::setAxis()
{
    QFont font = m_plot->xAxis->labelFont();
    font.setPixelSize(18);
    font.setBold(true);

    m_plot->xAxis->setLabelFont(font);
    m_plot->yAxis->setLabelFont(font);

    m_plot->xAxis->setTickLabelFont(font);
    m_plot->yAxis->setTickLabelFont(font);

    set_xAxis_UpperTextVisible();
}

void CustomPlotWdt::set_xAxis_UpperTextVisible()
{
    m_plot->yAxis2->setVisible(true);
    m_plot->yAxis2->setTickLabels(false);
    m_plot->yAxis2->setTickLength(0);
    m_plot->yAxis2->setSubTickLength(0);
    m_plot->yAxis2->setPadding(45);
}

MenuActionWdt.h

#pragma once
#include <QWidget>
#include <QLabel>
#include <QLineEdit>

class MenuActionWdt : public QWidget
{
    Q_OBJECT
public:
    MenuActionWdt(QWidget* parent);
    ~MenuActionWdt();

    void setLabelText(const QString& text);
    void setLineEditText(const QString& text);
    QString getLineEditText();

private:
    void init();

private:
    QLabel* m_label;
    QLineEdit* m_lineEdit;
};

MenuActionWdt.cpp
	
#include "MenuActionWdt.h"
#include <QHBoxLayout>

MenuActionWdt::MenuActionWdt(QWidget* parent)
    :QWidget(parent)
{
    init();
}


MenuActionWdt::~MenuActionWdt()
{
}

void MenuActionWdt::init()
{
    m_label = new QLabel(this);
    m_lineEdit = new QLineEdit(this);
    m_lineEdit->setReadOnly(true);

    QHBoxLayout* layout = new QHBoxLayout;
    layout->addWidget(m_label);
    layout->addWidget(m_lineEdit);
    layout->setSpacing(0);
    layout->setMargin(0);
    setLayout(layout);

    setMaximumWidth(100);
}

void MenuActionWdt::setLabelText(const QString& text)
{
    m_label->setText(text);
}

void MenuActionWdt::setLineEditText(const QString& text)
{
    m_lineEdit->setText(text);
}

QString MenuActionWdt::getLineEditText()
{
    return m_lineEdit->text();
}

IntToString.h

#pragma once
#include <QString>

typedef struct EnumToStringStruct
{
    int type;
    QString name;
}EnumToString;

class IntToString
{
public:
    IntToString();
    ~IntToString();

    static QString string(const EnumToString szEnumToString[], const int length, const int type);
    static bool AllisNum(std::string str);
};

IntToString.cpp

#include "IntToString.h"

IntToString::IntToString()
{
}
IntToString::~IntToString()
{
}
QString IntToString::string(const EnumToString szEnumToString[], const int length, const int type)
{
    for (int i = 0; i < length; i++)
    {
        if (type == szEnumToString[i].type)
        {
            return szEnumToString[i].name;
        }
    }
    return "";
}

bool IntToString::AllisNum(std::string str)
{
	if (str.empty())
		return false;
	int index = 0;
	if (str[0] == '-' || str[0] == '+')
		index = 1;
	if (index == 1 && str.size() == 1)
		return false;
	int radix_point = 0;
	for (; index < str.size(); index++)
	{
		char c = str[index];
		if (c == '.')
		{
			radix_point++;
			if (radix_point == 2)
				return false;
			else
				continue;
		}
		if (c >= '0' && c <= '9')
			continue;
		else
			return false;
	}
	return true;
}

MessageBoxCustom.h

#pragma once
#include <QString>

class MessageBoxCustom
{
public:
    MessageBoxCustom();
    ~MessageBoxCustom();

public:
    static void information(const QString& text);
    static void warning(const QString& text);
    static void critical(const QString& text);
    static void question(const QString& text);
private:
    static void showMessageBox(const int iconType, const QString &title, const QString& text);
};

MessageBoxCustom.cpp

#include "MessageBoxCustom.h"
#include <QMessageBox>
#include "Language.h"

MessageBoxCustom::MessageBoxCustom()
{
}


MessageBoxCustom::~MessageBoxCustom()
{
}

void MessageBoxCustom::showMessageBox(const int iconType, const QString &title, const QString& text)
{
    QMessageBox box((QMessageBox::Icon)iconType, title, text);
    box.setStandardButtons(QMessageBox::Ok);
    if (iconType == QMessageBox::Question)
    {
        box.setStandardButtons(QMessageBox::Ok | QMessageBox::Cancel);
        box.setButtonText(QMessageBox::Cancel, Trans("取消"));
    }
    box.setButtonText(QMessageBox::Ok, Trans("确定"));
    box.exec();
}

void MessageBoxCustom::information(const QString& text)
{
    showMessageBox(QMessageBox::Information, Trans("提示"), text);
}

void MessageBoxCustom::warning(const QString& text)
{
    showMessageBox(QMessageBox::Warning, Trans("警告"), text);
}

void MessageBoxCustom::critical(const QString& text)
{
    showMessageBox(QMessageBox::Critical, Trans("错误"), text);
}

void MessageBoxCustom::question(const QString& text)
{
    showMessageBox(QMessageBox::Question, Trans("提示"), text);
}

WidgetEx.h

#pragma once
#include <QWidget>

class WidgetEx : public QWidget
{
public:
    WidgetEx(QWidget* parent = nullptr);
    ~WidgetEx();
public:
    virtual void init();
protected:
    void setBackgroundColor(const QColor &color); 
};

WidgetEx.cpp

#include "WidgetEx.h"

WidgetEx::WidgetEx(QWidget* parent)
    : QWidget(parent)
{
    
}


WidgetEx::~WidgetEx()
{
}

void WidgetEx::setBackgroundColor(const QColor &color)
{
    QPalette pal(palette());
    pal.setColor(QPalette::Background, color);
    setAutoFillBackground(true);
    setPalette(pal);
}

void WidgetEx::init()
{
    setBackgroundColor(qRgb(224, 255, 255));
}

FileRelevance.h

#pragma once

#include <QString>

class FileRelevance
{
public:
    FileRelevance();
    ~FileRelevance();

    static QStringList getFileNamesFromPath(const QString &path, const QString &filter);
    static void removeDirectory(const QString &path);
    static bool makeDirectory(const QString &path);
};

FileRelevance.cpp

#include "FileRelevance.h"
#include <QDir>
FileRelevance::FileRelevance()
{
}
FileRelevance::~FileRelevance()
{
}
QStringList FileRelevance::getFileNamesFromPath(const QString &path, const QString &filter)
{
    QDir dir(path);
    QStringList nameFilters;
    nameFilters << filter;
    QStringList files = dir.entryList(nameFilters, QDir::Files | QDir::Readable, QDir::Name);
    return files;
}
void FileRelevance::removeDirectory(const QString &path)
{
    QDir dir(path);
    dir.removeRecursively();
}

bool FileRelevance::makeDirectory(const QString &path)
{
    QDir dir(path);
    if (dir.exists())
        return true;

    return dir.mkpath(path);
}

AnalysisRightWdt.h

#pragma once

#include "WidgetEx.h"
#include <QTimer>

class CustomPlotWdt;
class AnalysisRightWdt :public WidgetEx
{
    Q_OBJECT
public:
    AnalysisRightWdt(QWidget* parent);
    ~AnalysisRightWdt();

    void init();
protected:
    virtual void showEvent(QShowEvent *event);
    virtual void hideEvent(QHideEvent *event);
private slots:
    void slot_showData(const QVector<double>& vecKey, const QVector<double>& vecValue, const float xAxisUpper);
    void slot_customPlotWdt_get_current_xAxis_range();
private:
    void initCustomPlot();
    void initLayout();
    void connectSignalSlot();
    void disconnectSignalSlot();
private:
    CustomPlotWdt* m_plotWdt;
};

AnalysisRightWdt.cpp

#include "AnalysisRightWdt.h"
#include "ThreadCenter.h"
#include <QtMath>
#include "TestControl.h"
#include "MessageBoxCustom.h"
#include "HardwareGainNames.h"
#include "ParamConfig.h"
#include "FileHandler.h"
#include "DataAnalysis.h"
#include "CustomPlotWdt.h"

AnalysisRightWdt::AnalysisRightWdt(QWidget* parent):WidgetEx(parent){}
AnalysisRightWdt::~AnalysisRightWdt(){}
void AnalysisRightWdt::init()
{
    initCustomPlot();
    initLayout();
    //connectSignalSlot();
}

void AnalysisRightWdt::initLayout()
{
    QHBoxLayout* mainLayout = new QHBoxLayout();
    mainLayout->addWidget(m_plotWdt);
    mainLayout->setMargin(0);
    setLayout(mainLayout);
}

void AnalysisRightWdt::initCustomPlot()
{
    m_plotWdt = new CustomPlotWdt(this);
    m_plotWdt->init();
    m_plotWdt->setSelectRectEnable(true);
    m_plotWdt->setMenuEnable(true);
    
    connect(&DataAnalysisSingleton, &DataAnalysis::signal_timeSelectWdt_defaultBtnClicked, this, &AnalysisRightWdt::slot_customPlotWdt_get_current_xAxis_range);

    connect(m_plotWdt, &CustomPlotWdt::signal_timeSelect_T1, &DataAnalysisSingleton, &DataAnalysis::signal_customPlotWdt_timeSelect_T1);
    connect(m_plotWdt, &CustomPlotWdt::signal_timeSelect_T2, &DataAnalysisSingleton, &DataAnalysis::signal_customPlotWdt_timeSelect_T2);
    connect(m_plotWdt, &CustomPlotWdt::signal_selection_xAxis_range, &DataAnalysisSingleton, &DataAnalysis::signal_customPlotWdt_current_xAxis_range);
	connect(m_plotWdt, &CustomPlotWdt::SigDataSelectedToSend, &DataAnalysisSingleton, &DataAnalysis::SigDataSelectedToSend);

}

void AnalysisRightWdt::connectSignalSlot()
{
    qRegisterMetaType<QVector<double>>("QVector<double>");
    connect(&FileHandlerSingleton, &FileHandler::signal_fileHandle_complete, this, &AnalysisRightWdt::slot_showData);
    connect(&DataAnalysisSingleton, &DataAnalysis::signal_dataAnalysis_complete, this, &AnalysisRightWdt::slot_showData);
}

void AnalysisRightWdt::disconnectSignalSlot()
{
    disconnect(&FileHandlerSingleton, &FileHandler::signal_fileHandle_complete, this, &AnalysisRightWdt::slot_showData);
    disconnect(&DataAnalysisSingleton, &DataAnalysis::signal_dataAnalysis_complete, this, &AnalysisRightWdt::slot_showData);
}

void AnalysisRightWdt::showEvent(QShowEvent *event)
{
    connectSignalSlot();

    QStringList names = HardwareGainNamesSingleton.getNames().split(",");
    m_plotWdt->set_yAxis_name(names[Name_CURRENT]);
}

void AnalysisRightWdt::hideEvent(QHideEvent *event)
{
    disconnectSignalSlot();
}

void AnalysisRightWdt::slot_showData(const QVector<double>& vecKey, const QVector<double>& vecValue, const float xAxisUpper)
{
   // const QVector<double> testValue{0.05,0.05,0.05,0.05,0.05,0.05,0.05,0.05,0.05};
   // const QVector<double> testKey{1,2,3,4,5,6,7,8,9};
   // QVector<double>* test = &testVec;
    m_plotWdt->setData(vecKey, vecValue, true);
   // m_plotWdt->setData(testKey,testValue , true);
    if (!vecKey.isEmpty())
    {
        m_plotWdt->set_xAxis_range(0, xAxisUpper);
        m_plotWdt->reset_yAxis_range();
    }
        
    m_plotWdt->replot();
}

void AnalysisRightWdt::slot_customPlotWdt_get_current_xAxis_range()
{
    double lower, upper;
    m_plotWdt->get_xAxis_range(lower, upper);
    emit DataAnalysisSingleton.signal_customPlotWdt_current_xAxis_range((float)lower, (float)upper);
}

标签:plot,const,double,void,QCustomPlot,range,xAxis,使用
From: https://blog.csdn.net/weixin_45074487/article/details/137336302

相关文章

  • sql怎么使用三个判断
    在SQL中,你可以使用CASE语句来实现三个条件判断。CASE语句在SQL中可以提供一种灵活的方式来根据条件判断执行不同的操作。以下是一个简单的例子,假设我们有一个名为employees的表,它有一个名为salary的列,我们想要根据员工的薪水范围为他们分类:SELECTname,salary,CASE......
  • Linux进程API接口功能介绍和使用方法
    目录概述1进程基本操作1.1fork函数1.2终止进程1.3exec族函数1.4wait函数1.5守护进程2使用进程相关API的范例2.1创建进程2.1.1功能介绍2.1.2编写代码2.1.3运行结果2.2等待退出函数2.2.1功能介绍2.2.2编写代码2.2.3运行结果2.3使用守护进程2......
  • 单向链表使用
    单向链表包含解决的问题:求单链表中有效节点的个数查找单链表中的倒数第k个结点-使用双指针实现【新浪面试题】单链表的反转-通过栈的方式实现从尾到头打印单链表-方式1:递归实现。方式2:Stack栈实现合并两个有序的单链表,合并之后的链表依然有序。代码示例://定义......
  • 使用Python的turtle模块绘制美丽的樱花树
    引言Python的turtle模块是一个直观的图形化编程工具,让用户通过控制海龟在屏幕上的移动来绘制各种形状和图案。turtle模块的独特之处在于其简洁易懂的操作方式以及与用户的互动性。用户可以轻松地通过使用诸如前进、后退、左转、右转等基本命令,来编写程序控制海龟的行动路径,从而创......
  • C++多线程:async、future、packaged_task、promise、shared_future的学习与使用(九)
    1、异步任务线程异步线程的概念:异步:就是非同步,同步就是必须一个一个的执行,异步可以两个事情一起干异步线程:异步线程就相当于把非关联的两件事分开找两个线程去执行,而分开的那个就是异步线程举例:例如登录信息,用户登录完毕主线程肯定是需要去及时响应用户的请求的,而系统设......
  • dd if=devzero of=的含义是什么?Linux 下的dd命令使用详解
    ddif=/dev/zeroof=的含义是什么?Linux下的dd命令使用详解一、dd命令的解释dd:用指定大小的块拷贝一个文件,并在拷贝的同时进行指定的转换。注意:指定数字的地方若以下列字符结尾,则乘以相应的数字:b=512;c=1;k=1024;w=2参数注释:1.if=文件名:输入文件名,缺省为标准输入。即指定源文......
  • 使用POI填充Word文档,一些注意事项以及解决办法
    有这样一个需求:需要将用户输入的数据填写到准备好的Word模版中并提供下载,最终选择POI-tl和POI来完成上述需求。在这个过程中,主要遇到了以下两个问题:1.Word的两个格式doc和docx(两种文件的区别大家可以自行百度了解下),POI并没有提供统一的处理类。分别用HWPFDocument处理doc......
  • Typora 使用中的几个问题
    一、切换源代码模式快捷键修改:文件---偏好设置---通用---高级设置---打开高级设置,会打开C:\Users\Administrator\AppData\Roaming\Typora\conf目录,打开里面的conf.user.json文件,在keyBinding属性下,添加"源代码模式":"Ctrl+`",即可修改快捷键。二、编辑界面两边的空白:源......
  • OpenCV中表示图像的类Mat在QT里的基本使用
    在Qt中使用OpenCV的Mat类来表示和处理图像是相对简单的,因为Qt和OpenCV都是跨平台的,并且可以很好地在一起工作。以下是如何在Qt项目中使用OpenCV的Mat类的基本步骤:1.在Qt代码中包含OpenCV头文件在Qt的源代码文件中,你需要包含OpenCV的头文件以及opencv统一的命名空间来使用Mat......
  • 使用Spring管理Bean(一)
    一、IOC和DI1、简介IOC是InversionOfControl(控制反转)的缩写,它是一种设计思想,是指将对象的控制权由程序代码反转给外部容器。publicclassAccountServiceImplimplementsIAccountService{privateIAccountDaoaccountDao;publicAccoutServiceImpl({......