关于QCharts拖拽框缩放和平移功能的整合问题

TB boy 2024-10-11 15:53:46

想实现类似matplotlib工具栏功能,点击按钮可切换功能模式。但现在对于平移和拖拽框缩放这两个功能不知道如何整合到QChartView上
 

这是关于平移的代码

#include "chartview.h"
#include <QValueAxis>
#include <QApplication>

ChartView::ChartView(QWidget* parent)
    : QChartView{ parent }
    , prevPoint_{}
    , leftButtonPressed_{}
    , ctrlPressed_{}
    , alreadySaveRange_{}
    , xRange_{}
    , yRange_{}
    , coordItem_{}
{
    //设置橡皮筋拖动模式
    setDragMode(QGraphicsView::RubberBandDrag);
    //关闭鼠标跟踪
    setMouseTracking(false);

}

ChartView::ChartView(QChart *chart, QWidget *parent)
    : ChartView{ parent } // C++11 Delegating constructors
{
    setChart(chart);
}

ChartView::~ChartView()
{
}

void ChartView::mousePressEvent(QMouseEvent *event)
{
    if (event->button() == Qt::LeftButton) {
        if(m_isMoving){
            prevPoint_ = event->pos();
            leftButtonPressed_ = true;
        }
    }
}

void ChartView::mouseMoveEvent(QMouseEvent *event)
{
    if(m_isMoving){
        //创建文本
        if (!coordItem_) {
            coordItem_ = new QGraphicsSimpleTextItem{ chart() };
            coordItem_->setZValue(5);
            coordItem_->setPos(100, 60);
            coordItem_->show();
        }
        const QPoint curPos{ event->pos() };
        //将获取到的点进行准换为可带有小数位的坐标系点位
        const QPointF curVal{ chart()->mapToValue(QPointF(curPos)) };
        coordItem_->setText(QString("X = %1, Y = %2").arg(curVal.x()).arg(curVal.y()));

        if (leftButtonPressed_) {
            const auto offset = curPos - prevPoint_;
            prevPoint_ = curPos;
            if (!alreadySaveRange_) {
                saveAxisRange();
                alreadySaveRange_ = true;
            }
            chart()->scroll(-offset.x(), offset.y());
        }
    }
    else if(m_isTouching){
        return;
    }
}

void ChartView::mouseReleaseEvent(QMouseEvent *event)
{
    leftButtonPressed_ = false;
    if (event->button() == Qt::RightButton) {
        if (alreadySaveRange_) {
            chart()->axisX()->setRange(xRange_[0], xRange_[1]);
            chart()->axisY()->setRange(yRange_[0], yRange_[1]);
        }
    }

}

void ChartView::wheelEvent(QWheelEvent *event)
{
#if (QT_VERSION <= QT_VERSION_CHECK(6,0,0))
    const auto pos  = QPointF(event->pos());
    const auto isZoomIn = event->delta() > 0;
#else
    const auto pos  = event->position();
    const auto isZoomIn = event->angleDelta().y() > 0;
#endif
    const QPointF curVal = chart()->mapToValue(pos);

    if (!alreadySaveRange_) {
        saveAxisRange();
        alreadySaveRange_ = true;
    }

    auto zoom = [](QValueAxis* axis, double centre, bool zoomIn) {
        constexpr auto scaling{ 1.5 };

        const double down = axis->min();
        const double up = axis->max();

        double downOffset{};
        double upOffset{};
        if (zoomIn) {
            downOffset = (centre - down) / scaling;
            upOffset = (up - centre) / scaling;
        }
        else {
            downOffset = (centre - down) * scaling;
            upOffset = (up - centre) * scaling;
        }

        axis->setRange(centre - downOffset, centre + upOffset);
    };

    if (ctrlPressed_) {
        auto axis = qobject_cast<QValueAxis*>(chart()->axisY());
        zoom(axis, curVal.y(), isZoomIn);
    } else {
        auto axis = qobject_cast<QValueAxis*>(chart()->axisX());
        zoom(axis, curVal.x(), isZoomIn);
    }
}

void ChartView::keyPressEvent(QKeyEvent *event)
{
    if (event->key() == Qt::Key_Control)
        ctrlPressed_ = true;
}

void ChartView::keyReleaseEvent(QKeyEvent *event)
{
    if (event->key() == Qt::Key_Control)
        ctrlPressed_ = false;
}

void ChartView::saveAxisRange()
{
    const auto axisX = qobject_cast<QValueAxis*>(chart()->axisX());
    xRange_ = { axisX->min(), axisX->max() };
    const auto axisY = qobject_cast<QValueAxis*>(chart()->axisY());
    yRange_ = { axisY->min(), axisY->max() };
}




 

这是拖拽框缩放的代码
 

#include "chartview.h"

#include <QMouseEvent>
#include <QValueAxis>

ChartView::ChartView(QWidget *parent)
    : QChartView(parent)
{
    setRubberBand(QChartView::RectangleRubberBand);

}

ChartView::ChartView(QChart *chart, QWidget *parent)
    : QChartView(chart, parent)
{
    setRubberBand(QChartView::RectangleRubberBand);
}


bool ChartView::viewportEvent(QEvent *event)
{
    if (event->type() == QEvent::TouchBegin and m_enableTouchInitialization) {
        // By default touch events are converted to mouse events. So
        // after this event we will get a mouse event also but we want
        // to handle touch events as gestures only. So we need this safeguard
        // to block mouse events that are actually generated from touch.

        m_isTouching = true;

        // Turn off animations when handling gestures they
        // will only slow us down.
        chart()->setAnimationOptions(QChart::NoAnimation);
    }
    return QChartView::viewportEvent(event);
}

void ChartView::mousePressEvent(QMouseEvent *event)
{
    if(event->button()==Qt::LeftButton)
    {
        if (m_isTouching){
            return;

        }

    }

    QChartView::mousePressEvent(event);
}

void ChartView::mouseMoveEvent(QMouseEvent *event)
{
    if(event->button()==Qt::LeftButton)
    {
        if (m_isTouching){
            return;
        }

    }

    QChartView::mouseMoveEvent(event);
}

void ChartView::mouseReleaseEvent(QMouseEvent *event)
{
    buttonPress=false;
    if (m_isTouching)
        m_isTouching = false;
    if (m_isMoving)
        m_isMoving = false;

    chart()->setAnimationOptions(QChart::SeriesAnimations);

    QChartView::mouseReleaseEvent(event);
}

//![1]
void ChartView::keyPressEvent(QKeyEvent *event)
{
    switch (event->key()) {
    case Qt::Key_Plus:
        chart()->zoomIn();
        break;
    case Qt::Key_Minus:
        chart()->zoomOut();
        break;
//![1]
    default:
        QGraphicsView::keyPressEvent(event);
        break;
    }
}


###########################################
    setRubberBand(QChartView::NoRubberBand);
    setDragMode(QGraphicsView::RubberBandDrag);
###########################################
    setRubberBand(QChartView::RectangleRubberBand);
    setDragMode(QGraphicsView::NoDrag);

初步想法是设置模式,通过切换模式来实现不同功能,但不起作用,现在初始化为拖拽框缩放功能,点击切换后平移功能无法实现,现在不知道如何能将上述两种功能整合到一块,实现功能切换。
希望大佬们能给予一些建议,感谢各位了!

 

...全文
550 1 打赏 收藏 转发到动态 举报
写回复
用AI写文章
1 条回复
切换为时间正序
请发表友善的回复…
发表回复
赵4老师 2024-10-12
  • 打赏
  • 举报
回复

自绘是早晚要学会的技能

内容概要:本文围绕“基于改进秃鹰算法的微电网群经济优化调度”展开研究,利用Matlab代码实现优化算法的仿真与复现。研究重点在于通过改进的秃鹰搜索算法(Bald Eagle Search Algorithm, BESA)解决微电网群在运行过程中的经济调度问题,提升算法的收敛速度与全局寻优能力,以实现对分布式能源、储能系统及负荷的高效协调管理。文中详细阐述了微电网群的系统架构、数学建模过程、目标函数设计(如运行成本最小化、碳排放降低等),并结合智能优化算法进行求解,验证了改进算法相较于传统方法在调度精度和效率方面的优越性。同时,研究还探讨了算法在多场景下的适应性,为微电网群的智能化、低碳化运行提供了技术支持与实践参考。; 适合人群:具备一定电力系统基础知识和Matlab编程能力的研究生、科研人员及从事微电网、智能优化算法相关工作的工程技术人员。; 使用场景及目标:① 学习并掌握改进秃鹰算法在复杂优化问题中的应用方法;② 实现微电网群经济调度模型的构建与求解;③ 对比不同智能算法在电力系统优化中的性能表现;④ 为科研论文复现、课题研究或工程项目提供算法支持与代码参考。; 阅读建议:建议读者结合文中提供的Matlab代码逐模块分析,重点关注算法改进策略与调度模型的耦合实现方式,同时可尝试在不同参数设置或场景条件下进行仿真实验,以加深对算法性能与调度效果的理解。
内容概要:本文围绕多旋翼无人机姿态估计算法的开发与性能评估展开系统性研究,重点对比了线性与非线性滤波算法在复杂飞行环境下的表现。通过构建基于扩展卡尔曼滤波(EKF)、无迹卡尔曼滤波(UKF)等先进算法的姿态估计器,融合IMU、磁力计、视觉传感器等多源数据,有效提升了姿态解算的精度与鲁棒性。研究涵盖了静态悬停、高速机动及磁干扰等多种典型飞行场景,利用MATLAB/Simulink平台完成仿真实验,并结合实测飞行数据与VICON高精度运动捕捉系统提供的真值进行定量分析。结果表明,非线性滤波器在动态工况下具有显著优势,尤其在抑制漂移和抵抗外部干扰方面优于传统线性方法。文章还提出了传感器融合、自适应建模、冗余配置等一系列降低偏差影响的技术路径,为高可靠性无人机导航系统的设计提供了理论依据与实践指导。; 适合人群:具备控制理论、信号处理及状态估计基础知识,从事无人机导航、控制算法研发或相关领域研究的研究生、科研人员及工程技术人员。; 使用场景及目标:①用于开发高精度无人机姿态解算模块;②为多传感器融合算法的设计、实现与验证提供参考案例;③服务于复杂环境下无人系统状态估计的教学演示与科研攻关; 阅读建议:建议结合文中所述MATLAB/Simulink仿真模型与实测数据集进行复现与调试,重点关注EKF与UKF的数学推导、实现细节及关键参数调优过程,深入理解非线性系统建模、状态估计与工程实际之间的平衡与折衷。

21,499

社区成员

发帖
与我相关
我的任务
社区描述
Qt 是一个跨平台应用程序框架。通过使用 Qt,您可以一次性开发应用程序和用户界面,然后将其部署到多个桌面和嵌入式操作系统,而无需重复编写源代码。
社区管理员
  • Qt
  • 亭台六七座
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
暂无公告

试试用AI创作助手写篇文章吧