第三代软件开发-QCustomPlot核心迁移

简介: 欢迎来到我们的 QML & C++ 项目!这个项目结合了 QML(Qt Meta-Object Language)和 C++ 的强大功能,旨在开发出色的用户界面和高性能的后端逻辑。在项目中,我们利用 QML 的声明式语法和可视化设计能力创建出现代化的用户界面。通过直观的编码和可重用的组件,我们能够迅速开发出丰富多样的界面效果和动画效果。同时,我们利用 QML 强大的集成能力,轻松将 C++ 的底层逻辑和数据模型集成到前端界面中。在后端方面,我们使用 C++ 编写高性能的算法、数据处理和计算逻辑。C++ 是一种强大的编程语言,能够提供卓越的性能和可扩展性。我们的团队致力于优化代码,减少资

头图

第三代软件开发-QCustomPlot核心迁移

[toc]

关键字: QtQmlQCustomPlotGitHub Copilo关键字5

项目介绍

欢迎来到我们的 QML & C++ 项目!这个项目结合了 QML(Qt Meta-Object Language)和 C++ 的强大功能,旨在开发出色的用户界面和高性能的后端逻辑。

在项目中,我们利用 QML 的声明式语法和可视化设计能力创建出现代化的用户界面。通过直观的编码和可重用的组件,我们能够迅速开发出丰富多样的界面效果和动画效果。同时,我们利用 QML 强大的集成能力,轻松将 C++ 的底层逻辑和数据模型集成到前端界面中。

在后端方面,我们使用 C++ 编写高性能的算法、数据处理和计算逻辑。C++ 是一种强大的编程语言,能够提供卓越的性能和可扩展性。我们的团队致力于优化代码,减少资源消耗,以确保我们的项目在各种平台和设备上都能够高效运行。

无论您是对 QML 和 C++ 开发感兴趣,还是需要我们为您构建复杂的用户界面和后端逻辑,我们都随时准备为您提供支持。请随时联系我们,让我们一同打造现代化、高性能的 QML & C++ 项目!

重要说明☝

☀该专栏在第三代软开发更新完将涨价

先说点GitHub Copilot

为啥又要唠他了,上一篇咱们简单体验了GitHub Copilot一下,就粗略肤浅的把它定义为一个稍微智能点的智能补全工具,但是这的肤浅了,今天我在算是看到它的厉害之处了。

之前我们的数据需要做滤波处理,我们之前是怎么做的,在MATLAB里面模拟一下,完了导出一个数组出来,代码实现,大家应该都是这流程吧。来看看未来的样子,颤抖吧,宝宝们,下面是实际演示,可以看到类名都是我们项目里面的,没有半点掺假啊

这里就要聊到一个问题,我们传统的大学里面的VC6.0 还能满足当下的需求吗,理论非常重要,但是新时代的工具是不可或缺的一部分,我记得我工作的时候,学习的第一个东西竟然是SVN,大学里里面我都没有遇到过,更别说Git了,抛开我个人的能动性问题,是不是大学与实际脱离的有点远呢?

QCustomPlot核心迁移

聊回咱们的正题,今天咱们聊聊把QCustomPlot放进QML里面。为什么要废这个劲呢,Qt不是有QChart了,这个已经是历史问题了,因为在第一代和第二代中,咱们都用的是QCustomPlot来绘制曲线,而QChar 经过咱们的测试在QWidget下是不满足需求的,或者说是咱们驾驭不了的,加上第一代第二代的磨练,咱们稍微对这个QCustomPlot有了那么一丢丢的经验,所以就还是直接用了。但是呢,咱么这智商,这种东西哪里是咱能会的东西,直接求助百度,抄作业就行。

QQuickPaintedItem

这里咱们需要介绍一个类QQuickPaintedItem

QQuickPaintedItem是Qt Quick框架中的一个类,它用于在Qt Quick界面中进行自定义绘制。它允许开发者使用自己的绘图代码来创建可在Qt Quick场景中显示的项。

QQuickPaintedItem是QQuickItem的子类,它继承了QQuickItem的特性和功能。与其他QQuickItem不同的是,QQuickPaintedItem通过重写其父类的虚函数来实现自定义绘制。主要的绘制函数是void QQuickPaintedItem::paint(QPainter *painter)。在这个函数中,开发者可以使用QPainter对象进行2D绘图操作,如绘制图形、文本和图像等。

使用QQuickPaintedItem,开发者可以利用自己的绘图算法和技术创建自定义的Qt Quick组件。例如,可以使用QPainter绘制动态图形、数据可视化效果或自定义的UI元素等。由于QQuickPaintedItem提供了对底层绘图API(QPainter)的直接访问,因此它在某些情况下比使用纯Qt Quick元素更灵活。

要在Qt Quick界面中使用QQuickPaintedItem,可以将其作为一个子项添加到QML布局中,并设置其属性和信号槽等。同时,可以通过继承QQuickPaintedItem类来自定义更多的绘图行为和功能。

需要注意的是,由于QQuickPaintedItem直接操作底层绘图API,因此在性能要求较高的场景中,应当谨慎使用,并避免执行过于复杂或频繁的绘图操作,以保证良好的用户体验。

机器的语言总是生硬的,让人感觉不到一点温度,咱们还是看看真实博主的博客吧,看看今天有那个倒霉蛋让我们逮住抄作业了。

https://blog.csdn.net/LIJIWEI0611/article/details/124103346

image-20230727221811629

这位博主和机器人共同提到一个问题,那就是在性能要求较高的场景中,应当谨慎使用阿西,虽能告诉我,除了这个方法,还有什么法子会提高性能。因为我就是这么写的。以下内用引用之上方博客

Qt Quick 的核心是 Scene Graph ,可以在 Qt 帮助的索引模式下以 “Scene Graph” 为关键字来检索学习。 Scene Graph 的设计思想和 QGraphicsView/QGraphicsScene 框架类似,一个场景,很多图元往场景里放。不同之处是 Item 的绘制, QGraphicsView 框架里是通过 View 的绘图事件来驱动 Item 的绘制,QGraphicsItem 有一个 paint() 虚函数,只要你从 QGraphicsItem 继承来的 Item 实现这个 paint() 函数,就可以往 QPaintDevice 上绘制了,逻辑直接;而 Qt Quick 的绘制,其实另有一个渲染线程, Scene 里的 Item 没有 paint() 这种直观的绘图函数,只有一个 updatePaintNode() 方法让你来构造你的 Item 的几何表示,当程序轮转到渲染循环时,渲染循环把所有 Item 的 QSGNode 树取出来绘制。

updatePaintNode() 这种绘制的方式很不直观,它来自 OpenGL 或者 Direct 3D 的绘图模式:你构造图元的几何表示,别人会在某一个时刻根据你提供的材料帮你绘制,就像你扔一袋垃圾到门口,过一阵子有人会来帮你收走这种感觉。用惯 Qt Widgets 和 QPainter 的开发者可能会不适应这种方式,所以 Qt Quick 提供了一种兼容老习惯的方式:引入 QQuickPaintedItem ,使用 QPainter 绘制。

一般地,你可以这样理解: QQuickPaintedItem 使用 Qt Widgets 里惯常的 2D 绘图方式,将你想要的线条、图片、文字等绘制到一个内存中的 QImage 上,然后把这个 QImage 作为一个 QSGNode 放在那里等着 Qt Quick 的渲染线程来取走它,把它绘制到实际的场景中。按照这种理解, QQuickPaintedItem 会多个绘图步骤,有性能上的损失!不过为了开发方便,有时候这一点点性能损失是可以承受的——只要你的应用仍然可以流畅运行。

QQuickPaintedItem 是一切想使用 QPainter 来绘图的 Qt Quick Item 的基类,它有一个纯虚函数—— paint(QPainter * painter) ,你自定义的 Item 只要实现 paint() 虚函数就可以了。

QQuickPaintedItem 是 QQuickItem 的派生类, QQuickItem 的 boundingRect() 方法返回一个 Item 的矩形,你可以根据它来绘制你的 Item 。fillColor() 返回 Item 的填充颜色(默认是透明的), Qt Quick 会使用这个颜色在 paint() 方法调用前绘制你的 Item 的背景。 setFillColor() 可以改变填充颜色。

Qt Quick 提供了一个“Scene Graph - Painted Item”示例来演示 QQuickPaintedItem 的用法,你可以参考。

XXX_QCustomChart


#include <QQuickPaintedItem>
#include <QObject>
#include <QtQuick>
class QCustomPlot;
class QCPAbstractPlottable;

class XXX : public QQuickPaintedItem
{
    Q_OBJECT
public:
    explicit XXXX(QQuickItem *parent = nullptr);

    virtual ~XXXX();

    void paint(QPainter *painter) override;

    virtual void initChartUI(){};

    QCustomPlot *getPlot();

protected:
    virtual void hoverMoveEvent(QHoverEvent *event) override;

    virtual void mousePressEvent( QMouseEvent* event ) override;

    virtual void mouseReleaseEvent( QMouseEvent* event ) override;

    virtual void mouseMoveEvent( QMouseEvent* event ) override;

    virtual void mouseDoubleClickEvent( QMouseEvent* event ) override;

    virtual void wheelEvent( QWheelEvent *event ) override;

    void routeMouseEvents( QMouseEvent* event );

    void routeWheelEvents( QWheelEvent* event );

public slots:
    void graphClicked( QCPAbstractPlottable* plottable );

    void onChartViewReplot();

    void updateChartViewSize();

private:
    QCustomPlot*                    m_customPlot                = nullptr;
};



#endif //
#include "QCustomPlot/qcustomplot.h"
#include <QDebug>
XXX::XXX(QQuickItem *parent): QQuickPaintedItem(parent),m_customPlot(new QCustomPlot())
{
    setFlag(QQuickItem::ItemHasContents, true);                                     // 表示该项目具有可视内容,应由场景视图呈现
    setAcceptedMouseButtons(Qt::AllButtons);                                        // 设置接受的鼠标按钮
    setAcceptHoverEvents(true);                                                     // 接受鼠标悬停事件
    m_customPlot->setOpenGl(false);                                                  // 打开是使用OpenGL渲染
    connect(this, &QQuickPaintedItem::widthChanged,
            this, &XXXX::updateChartViewSize);                       // 更新窗口
    connect(this, &QQuickPaintedItem::heightChanged,
            this, &XXXX::updateChartViewSize);                       // 更新窗口

//        m_customPlot->setBackground(QBrush(QColor(255,255,255,255)));                         // 设置背景颜色
    //    m_customPlot->xAxis->setVisible(false);                                         // 不显示横坐标
    //    m_customPlot->yAxis->setVisible(false);                                         // 不显示纵坐标
    //    m_customPlot->setInteractions( QCP::iRangeDrag | QCP::iRangeZoom );             // 可以放大缩小,上下左右滑动
    //    m_customPlot->setSelectionRectMode(QCP::SelectionRectMode::srmZoom);            // 框选放大

}

XXX::~XXX()
{
    delete m_customPlot;
}

void XXXX::paint(QPainter *painter)
{
    if (!painter->isActive())
        return;
    QPixmap    picture( boundingRect().size().toSize() );
    QCPPainter qcpPainter( &picture );
    m_customPlot->toPainter(&qcpPainter);
    painter->drawPixmap(QPoint(), picture);

}

QCustomPlot *XXXX::getPlot()
{
    return m_customPlot;
}

void XXXX::hoverMoveEvent(QHoverEvent *event)
{
    Q_UNUSED(event)
}

void XXXX::mousePressEvent(QMouseEvent *event)
{
    routeMouseEvents(event);
}

void XXXX::mouseReleaseEvent(QMouseEvent *event)
{
    routeMouseEvents(event);
}

void XXXX::mouseMoveEvent(QMouseEvent *event)
{
    routeMouseEvents(event);
}

void XXXX::mouseDoubleClickEvent(QMouseEvent *event)
{
    routeMouseEvents(event);
}

void XXXX::wheelEvent(QWheelEvent *event)
{
    routeWheelEvents( event );
}

void XXXX::routeMouseEvents(QMouseEvent *event)
{
    QMouseEvent* newEvent = new QMouseEvent(event->type(), event->localPos(), event->button(), event->buttons(), event->modifiers());
    QCoreApplication::postEvent(m_customPlot, newEvent);
}

void XXXX::routeWheelEvents(QWheelEvent *event)
{
    QWheelEvent* newEvent = new QWheelEvent(event->pos(), event->delta(), event->buttons(), event->modifiers(), event->orientation());
    QCoreApplication::postEvent(m_customPlot, newEvent);
}

void XXXX::graphClicked(QCPAbstractPlottable *plottable)
{
    qDebug() << Q_FUNC_INFO << QString( "Clicked on graph '%1 " ).arg( plottable->name() );
}

void XXXX::onChartViewReplot()
{
    update();
}

void XXXX::updateChartViewSize()
{
    m_customPlot->setGeometry(0, 0, (int)width(), (int)height());
    m_customPlot->setViewport(QRect(0, 0, (int)width(), (int)height()));
}

博客签名2021

相关文章
|
5月前
|
敏捷开发 弹性计算 中间件
平台即服务(PaaS):简化开发与部署的新篇章
【6月更文挑战第21天】PaaS简化了应用开发与部署,提供资源池化、自动化管理及丰富的开发工具,助力企业降低成本、提高效率和系统稳定性。它支持敏捷开发、加速产品上市,改善用户体验,并推动创新,成为现代软件开发的关键。
|
6月前
|
Dubbo 前端开发 Java
让你在组建企业级项目时手到擒来——浅谈各类常用工具和框架概述
让你在组建企业级项目时手到擒来——浅谈各类常用工具和框架概述
|
前端开发 算法 数据可视化
第三代软件开发-C++&QML交互
欢迎来到我们的 QML & C++ 项目!这个项目结合了 QML(Qt Meta-Object Language)和 C++ 的强大功能,旨在开发出色的用户界面和高性能的后端逻辑。 在项目中,我们利用 QML 的声明式语法和可视化设计能力创建出现代化的用户界面。通过直观的编码和可重用的组件,我们能够迅速开发出丰富多样的界面效果和动画效果。同时,我们利用 QML 强大的集成能力,轻松将 C++ 的底层逻辑和数据模型集成到前端界面中。 在后端方面,我们使用 C++ 编写高性能的算法、数据处理和计算逻辑。C++ 是一种强大的编程语言,能够提供卓越的性能和可扩展性。我们的团队致力于优化代码,减少资
|
3月前
|
IDE 前端开发 API
OpenSumi问题之OpenSumi 与 Theia 相比有什么优势
OpenSumi问题之OpenSumi 与 Theia 相比有什么优势
|
3月前
|
缓存 开发者 测试技术
跨平台应用开发必备秘籍:运用 Uno Platform 打造高性能与优雅设计兼备的多平台应用,全面解析从代码共享到最佳实践的每一个细节
【8月更文挑战第31天】Uno Platform 是一种强大的工具,允许开发者使用 C# 和 XAML 构建跨平台应用。本文探讨了 Uno Platform 中实现跨平台应用的最佳实践,包括代码共享、平台特定功能、性能优化及测试等方面。通过共享代码、采用 MVVM 模式、使用条件编译指令以及优化性能,开发者可以高效构建高质量应用。Uno Platform 支持多种测试方法,确保应用在各平台上的稳定性和可靠性。这使得 Uno Platform 成为个人项目和企业应用的理想选择。
54 0
|
5月前
|
传感器 物联网 数据中心
探索ARM架构及其核心系列应用和优势
ARM架构因其高效、低功耗和灵活的设计,已成为现代电子设备的核心处理器选择。Cortex-A、Cortex-R和Cortex-M系列分别针对高性能计算、实时系统和低功耗嵌入式应用,满足了不同领域的需求。无论是智能手机、嵌入式控制系统,还是物联网设备,ARM架构都以其卓越的性能和灵活性在全球市场中占据了重要地位。
247 1
|
算法 数据可视化 前端开发
第三代软件开发-Qt属性系统
欢迎来到我们的 QML & C++ 项目!这个项目结合了 QML(Qt Meta-Object Language)和 C++ 的强大功能,旨在开发出色的用户界面和高性能的后端逻辑。 在项目中,我们利用 QML 的声明式语法和可视化设计能力创建出现代化的用户界面。通过直观的编码和可重用的组件,我们能够迅速开发出丰富多样的界面效果和动画效果。同时,我们利用 QML 强大的集成能力,轻松将 C++ 的底层逻辑和数据模型集成到前端界面中。 在后端方面,我们使用 C++ 编写高性能的算法、数据处理和计算逻辑。C++ 是一种强大的编程语言,能够提供卓越的性能和可扩展性。我们的团队致力于优化代码,减少资
|
测试技术 API 调度
【老司机平台技术】构建应用级项目集成任务通用实验室
欢迎使用老司机平台,共同推进高效业务测试体验,地址:http://drivers.alibaba.net/背景老司机项目集成任务原计划为每一个项目老司机创建一个实验室,当项目环境部署时,会拉起这个实验室,然后触发老司机的项目集成任务。项目集成任务本身配置可触发的项目标,通过与实验室传递的项目标匹配以判断是否真正执行此集成任务。这里存在几个问题:如果每个项目都创建一个实验室,那么最终同一个应用上存在
427 0
【老司机平台技术】构建应用级项目集成任务通用实验室
|
架构师
「业务架构」业务架构师的工具箱:简介
「业务架构」业务架构师的工具箱:简介
|
缓存 IDE 编译器
鲲鹏系列一: DevKit代码迁移工具技术要点总结
处理器所支持的指令集不同,意味着开发者可能需要对代码进行跨平台的迁移。通常,代码迁移是件复杂又繁琐的工作,需要花费开发者大量精力对软件包、源代码、依赖库文件进行人工分析、检查和识别,手动修正不同指令集之间的相关差异,这些差异主要涉及语法、指令、函数和库文件支持情况。
487 0
鲲鹏系列一: DevKit代码迁移工具技术要点总结