近期关注 Qt 6.10 的分支进展, 发现了 Qt 6.10 的 charts 和 data visualization (以下简称 DV)已经被deprecated, 功能将会合并到 graphs 模块。如果后面 charts\ DV 被弃用,那算是很大的API变化了。从Qt 6.5 以后开始引入的 graphs 使用的是QML的渲染器,和之前的 Qt Widgets GraphicsView 完全不同。如果有依赖上述模块的应用,需要提前评估API的变化。

1. 可能遇到的主要问题

只要是和QML相关的东西,那问题无外乎就是老电脑的兼容性,以及跨语言的API。

1.1 老旧和低成本环境可能不再适用

QML的渲染器过度依赖OS的本地3D加速API,如 Windows的 DirectX。在VMWare/VirtualBox环境下,QML有概率无法正常渲染图形。在只有核心显卡,没有配置独立显卡的低成本计算机上,QML也非常卡顿,甚至可能无法启动(如果驱动比较老或者配置不正确)。

与之形成对比的,是Widgets的2D渲染,基本是在backend里自绘的,因此,不但可以支持老旧计算机,还能在 vnc、framebuf里使用。

1.2 跨语言API调用和性能问题

charts和DV是支持C++ Only模式的开发的。但是, graphs 却不是。官网的例子里,C++ Widgets 程序使用 graphs 必须要进行QML混合编程。这里就牵扯到三个场景:

  1. 从C++中动态向 QML 刷新曲线,特别是1秒刷新23次的这种动画。
  2. 从C++中精确获得QML图元的signal,如橡皮筋选择、有图元被双击等等。
  3. 从C++中查询各个图元的属性和状态。比如查询视图的宽度、高度,选中的状态等。

这些操作要达到高性能、易于使用,需要特别注意不出现内存深度拷贝,且管理好QObject对象树的生命周期(life-cycle)。

2. 初步试用

抱着试试看的态度,初步对 Qt Graphs的API进行了研究,并以最简单的动态折线图进行了开发测试。

pro文件

模块包括 quickwidgets graphs quick 等模块。

QT       += core gui widgets quickwidgets graphs quickCONFIG += c++17SOURCES += \main.cpp \graphstest.cppHEADERS += \graphstest.hFORMS += \graphstest.ui

2.2 main.cpp

#include "graphstest.h"#include <QApplication>int main(int argc, char *argv[])
{QApplication a(argc, argv);graphsTest w;w.show();return a.exec();
}

2.3 graphstest.h

#ifndef GRAPHSTEST_H
#define GRAPHSTEST_H#include <QDateTimeAxis>
#include <QDialog>
#include <QLineSeries>
#include <QValueAxis>
#include <QVector>
QT_BEGIN_NAMESPACE
namespace Ui
{
class graphsTest;
}
QT_END_NAMESPACEclass graphsTest : public QDialog
{Q_OBJECTpublic:graphsTest(QWidget *parent = nullptr);~graphsTest();protected:void timerEvent(QTimerEvent *evt) override;
private slots:void on_pushButton_add_clicked();void on_checkBox_update_clicked();private:Ui::graphsTest *ui;QDateTimeAxis *m_ax;QValueAxis *m_ay;int m_timerEvent;QVector<QLineSeries *> m_lineSeries;
};
#endif // GRAPHSTEST_H

2.4 graphstest.cpp

#include "graphstest.h"
#include <QDateTime>
#include <QDebug>
#include <QQuickItem>
#include "ui_graphstest.h"
graphsTest::graphsTest(QWidget *parent): QDialog(parent), ui(new Ui::graphsTest), m_ax(new QDateTimeAxis(this)), m_ay(new QValueAxis(this)), m_timerEvent(-1)
{ui->setupUi(this);QDateTime dtmNow = QDateTime::currentDateTime();m_ax->setMin(dtmNow.addDays(-1));m_ax->setMax(dtmNow);m_ay->setRange(-100, 100);QList<QObject *> seriesList;ui->graphsView->setResizeMode(QQuickWidget::SizeRootObjectToView);ui->graphsView->setInitialProperties({{"seriesList", QVariant::fromValue(seriesList)},{"axisX", QVariant::fromValue(m_ax)},{"axisY", QVariant::fromValue(m_ay)},{"zoomAreaEnabled", true}});ui->graphsView->loadFromModule("QtGraphs", "GraphsView");
}graphsTest::~graphsTest()
{delete ui;
}void graphsTest::timerEvent(QTimerEvent *evt)
{if (evt->timerId() == m_timerEvent){QList<QPointF> data;QDateTime dtmNow = QDateTime::currentDateTime();const int N = m_lineSeries.size();for (int n = 0; n < N; ++n){for (int i = 0; i < 30; ++i){data << QPointF(dtmNow.addSecs(-3600 * 24.0 / 30 * (29 - i)).toMSecsSinceEpoch(),(rand() % 500 - 250) / 100.0 + n * 16 - 80);}m_lineSeries[n]->replace(data);}m_ax->setMin(dtmNow.addDays(-1));m_ax->setMax(dtmNow);if (!ui->checkBox_update->isChecked()){killTimer(m_timerEvent);m_timerEvent = -1;}}QDialog::timerEvent(evt);
}void graphsTest::on_pushButton_add_clicked()
{if (m_lineSeries.size() >= 10)return;//Add to GraphQVariant seriesListVariant = ui->graphsView->rootObject()->property("seriesList");if (seriesListVariant.canConvert<QQmlListProperty<QObject>>()){QLineSeries *newLine = new QLineSeries(this);newLine->setColor(QColor(rand() % 128, rand() % 128, rand() % 128));newLine->setHoverable(true);newLine->setName(QString("Testing %1").arg(m_lineSeries.size()));connect(newLine,&QAbstractSeries::hover,[this](const QString &seriesName, QPointF position, QPointF value) -> void{ui->lineEdit_msg->setText(QString("%1:%2 %3 = %4 %5").arg(seriesName).arg(position.x()).arg(position.y()).arg(value.x()).arg(value.y()));});//AddQQmlListProperty<QObject> prop = seriesListVariant.value<QQmlListProperty<QObject>>();prop.append(&prop, newLine);m_lineSeries.append(newLine);}if (m_timerEvent < 0)m_timerEvent = startTimer(500);
}void graphsTest::on_checkBox_update_clicked()
{if (ui->checkBox_update->isChecked())m_timerEvent = startTimer(500);
}

2.5 graphstest.ui

<?xml version="1.0" encoding="UTF-8"?>
<ui version="4.0"><class>graphsTest</class><widget class="QDialog" name="graphsTest"><property name="geometry"><rect><x>0</x><y>0</y><width>579</width><height>332</height></rect></property><property name="windowTitle"><string>graphsTest</string></property><layout class="QVBoxLayout" name="verticalLayout_2"><item><layout class="QHBoxLayout" name="horizontalLayout"><item><widget class="QQuickWidget" name="graphsView"><property name="resizeMode"><enum>QQuickWidget::ResizeMode::SizeRootObjectToView</enum></property></widget></item><item><layout class="QVBoxLayout" name="verticalLayout"><property name="sizeConstraint"><enum>QLayout::SizeConstraint::SetMaximumSize</enum></property><item><widget class="QPushButton" name="pushButton_add"><property name="sizePolicy"><sizepolicy hsizetype="Fixed" vsizetype="Fixed"><horstretch>0</horstretch><verstretch>0</verstretch></sizepolicy></property><property name="text"><string>Add Serials</string></property></widget></item><item><widget class="QCheckBox" name="checkBox_update"><property name="sizePolicy"><sizepolicy hsizetype="Maximum" vsizetype="Fixed"><horstretch>0</horstretch><verstretch>0</verstretch></sizepolicy></property><property name="text"><string>Updating</string></property></widget></item><item><spacer name="verticalSpacer"><property name="sizePolicy"><sizepolicy hsizetype="Fixed" vsizetype="Expanding"><horstretch>0</horstretch><verstretch>0</verstretch></sizepolicy></property><property name="orientation"><enum>Qt::Orientation::Vertical</enum></property><property name="sizeHint" stdset="0"><size><width>20</width><height>40</height></size></property></spacer></item></layout></item></layout></item><item><widget class="QLineEdit" name="lineEdit_msg"><property name="sizePolicy"><sizepolicy hsizetype="Expanding" vsizetype="Fixed"><horstretch>0</horstretch><verstretch>0</verstretch></sizepolicy></property></widget></item></layout></widget><customwidgets><customwidget><class>QQuickWidget</class><extends>QWidget</extends><header location="global">QtQuickWidgets/QQuickWidget</header></customwidget></customwidgets><resources/><connections/>
</ui>

3. 运行效果

运行效果如下,主要问题包括(BUG):

  1. 新插入的对象的色彩,会影响到旧对象的色彩。
  2. 各个连线的收尾会连接起来。

add

4 评价

Qt 团队看起来对传统的 Widgets 已经不是很愿意维护了,这种大规模的API变化,以及完全不顾及兼容老计算机、集成显卡的环境的激进改进,要么是公司no zuo no die,要么说明QML技术的趋势已经势不可挡。

QML技术与C++的紧密互动,相当程度的缓解了API跨语言的问题,其实QML就是个调用C++ QObject 运行时的胶水语言,其和C++的联系非常紧密。对Qt Widgets而言,如果使用了 QML的功能,就会在硬件兼容性上面大打折扣,这对于很多桌面场景而言是不能接受的。对未来技术的发展,我们会保持持续的跟踪,并适时为我们使用 charts 的既有代码进行 graphs的适配,并在具备 charts 的环境下优先使用 charts.

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。
如若转载,请注明出处:http://www.pswp.cn/bicheng/89846.shtml
繁体地址,请注明出处:http://hk.pswp.cn/bicheng/89846.shtml
英文地址,请注明出处:http://en.pswp.cn/bicheng/89846.shtml

如若内容造成侵权/违法违规/事实不符,请联系英文站点网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

2025牛客暑期多校训练营2(部分补题)

题目链接&#xff1a;牛客竞赛_ACM/NOI/CSP/CCPC/ICPC算法编程高难度练习赛_牛客竞赛OJ B Bitwise Perfect 思路 考虑到由&#xff0c;那么只有变小的时候对答案的贡献才能够减少&#xff0c;从二进制的角度考虑什么时候变小&#xff0c;只有min(x,y)中的最高位1异或之后变…

Nginx的location匹配规则

Nginx的location匹配规则 为什么你的Nginx配置总是不生效&#xff1f; 改了Nginx配置无数次&#xff0c;reload命令执行了几十遍&#xff0c;浏览器访问时却依然返回404&#xff1f;运维工程师小张上周就遇到了这个问题&#xff1a;明明配置了location /static/ { root /var/ww…

USB 2.0 vs USB 3.0:全面技术对比与选择指南

USB 2.0 vs USB 3.0&#xff1a;全面技术对比与选择指南 引言 在当今数字时代&#xff0c;USB接口已成为连接设备与计算机的最普遍标准之一。从2000年USB 2.0的发布到2008年USB 3.0的问世&#xff0c;USB技术经历了显著的演进。本文将深入比较这两种广泛使用的USB标准&#xff…

DApp架构设计与开发流程指南

目录 DApp架构设计与开发流程指南 引言:DApp的核心特性 一、DApp架构设计 1.1 分层架构设计 各层核心组件: 1.2 典型架构模式 1.2.1 全去中心化架构 1.2.2 混合架构(推荐) 二、开发流程 2.1 敏捷开发流程 2.2 详细开发阶段 阶段1:需求分析与设计(1-2周) 阶段2:智能合约…

Windows下odbc配置连接SQL Server

一、查看SQL Server服务是否启动打开SQL Server 2022配置管理器查看SQL Server运行状态&#xff0c;可以设置 启动或停止服务二、windows下如何配置ODBC数据源1、Windows搜索栏中输入“ODBC数据源管理器”并选择“以管理员身份运行”来打开它2、添加新的数据源ODBC数据源管理器…

MySQL—表设计和聚合函数以及正则表达式

文章目录一、第一范式&#xff08;原子性&#xff09;二、第二范式&#xff08;消除部分依赖&#xff09;三、第三范式&#xff08;消除传递依赖&#xff09;四、表设计五、聚合函数六、正则表达式MySQL 的三大范式&#xff08;1NF、2NF、3NF&#xff09;是关系型数据库设计的核…

基于Electron打包jar成Windows应用程序

基于Electron打包jar成Windows应用程序简介注意编译及命令&#xff1a;运行效果登录界面用户管理界面界面全屏锁屏界面文档查看界面简介 本文介绍了一种将maven jar包打包成Windows下EXE可执行程序的方法。 Maven打包Java Web应用成jar&#xff0c;Electron封装jar成Windows …

Autosar RTE实现观测量生成-基于ETAS软件

文章目录前言观测量定义arTypedPerInstanceMemoryPorts Measurable工具链配置及使用Port中的配置arTypedPerInstanceMemory观测量生成文件分析总结前言 之前我们在XCP中&#xff0c;对于标定量和观测量并没有严格按照Autosar标准中定义&#xff0c;Autosar RTE中对标定量和观测…

【REACT18.x】creat-react-app在添加eslint时报错Environment key “jest/globals“ is unknown

今天在创建新项目的时候&#xff0c;给cra创建的项目添加eslint支持&#xff0c;出现如下报错 添加eslint npx eslint --init页面报错 Compiled with problems:ERROR [eslint] package.json eslint-config-react-app/jest#overrides[0]:Environment key "jest/globals&…

Linux的例行性工作 -- (练习)

1、atd和crond两个任务管理程序的区别 答&#xff1a; atd 专为一次性任务设计&#xff0c;允许用户在特定未来时间点&#xff08;绝对或相对时间&#xff09;执行单次命令后就结束。 crond 则是周期性任务的调度核心&#xff0c;通过配置文件&#xff08;crontab&#xff09;实…

《Java语言程序设计》1.6 复习题

1.6.1 什么是Java语言规范?计算机有严格的使用规则。如果编写程序时没有遵循这些规则&#xff0c;计算机就不能理解程序。Java语言规范和Java API定义了Java的标准。Java语言规范(Java language specification)是对Java程序设计语言的语法和语义的技术定义。应用程序接口(Appl…

【机器学习深度学习】什么是量化?

目录 前言 一、量化的基本概念 1.1 量化对比示例 1.2 量化是如何实现的&#xff1f; 二、为什么要进行量化&#xff1f; 2.1 解决模型体积过大问题 2.2 降低对算力的依赖 2.3 加速模型训练和推理 2.4 优化训练过程 2.5 降低部署成本 小结&#xff1a;量化的应用场…

告别 T+1!解密金融级实时数据平台的构建与实践

在数字金融浪潮下&#xff0c;数据处理的“实时性”已不再是加分项&#xff0c;而是逐渐成为决定业务价值的核心竞争力。然而&#xff0c;金融机构在追求实时的道路上&#xff0c;往往陷入一个新的困境&#xff1a;实时分析系统与离线大数据平台形成了两套独立的“烟囱”&#…

[Python] -项目实战7- 用Python和Tkinter做一个图形界面小游戏

一、为什么从小游戏入门GUI? 趣味性强:小游戏直观、有趣,一学就上手。 系统掌握事件驱动:了解按钮点击、键盘响应、图形刷新机制。 扎实基础:为日后构建更复杂应用奠定 GUI 编程基础。 二、选定游戏:猜数字小游戏 🎯 这个小游戏界面简单,核心机制是:3 个按钮分别…

【18】MFC入门到精通——MFC(VS2019)+ OpenCV 显示图片的3种方法

MFC (VS2019)+ OpenCV,显示图片的3种方法 1 方法介绍 2 方法一:嵌套OpenCV窗口显示图片 2.1 建立供工程 添加控件 2.2 引用头文件 2.3 找到OnInitDialog()函数,在其中添加如下代码 2.4 在button触发函数中加入代码(就是你双击button进入的函数) 2.5 注意事项 3 方法二:…

以“融合进化 智领未来”之名,金仓Kingbase FlySync:国产数据库技术的突破与创新

目录开篇&#xff1a;国产数据库的历史性跨越一、KFS 产品定位及发展历程回顾1.1 Kingbase FlySync 发展1.2 Kingbase FlySync与Oracle GoldenGate的对比分析1.2.1 Kingbase FlySync 功能优势1.2.2 技术架构对比1.2.3 性能与扩展性二、数字化时代的新挑战2.1 决策实时性要求越来…

服务器配置错误漏洞

文章目录一、文件解析漏洞1.Apache HTTPD多后缀解析漏洞二、目录遍历漏洞1.Apache目录遍历漏洞2.Nginx目录穿越漏洞服务器配置错误漏洞指因服务器&#xff08;含系统、Web服务、数据库等&#xff09;的参数设置、权限分配、组件配置等不当&#xff0c;导致的安全问题&#xff0…

大模型预测输尿管上段结石技术方案大纲

目录 1. 术前阶段 2. 术中阶段 3. 术后阶段 4. 并发症风险预测 5. 根据预测定手术方案 6. 麻醉方案 7. 术后护理 8. 统计分析 9. 技术验证方法 10. 实验证据 11. 健康教育与指导 12. 完整术方案流程图(Mermaid) 1. 术前阶段 步骤 关键要素 可编辑字段 1.1 影像采集 CT-IVU / …

docker compose 编排容器 mysql Springboot应用

写一个docker-compose.yml文件 内容如下&#xff1a; services:db:image: "docker.xuanyuan.me/library/mysql:8.3.0"restart: unless-stoppedhostname: dbports:- "3306:3306"container_name: mysqlenvironment:- "MYSQL_ROOT_PASSWORD1234"m…

React 中 props 的最常用用法精选+useContext

✅ React 最常用 props 用法 10 例✅ 1. 传递字符串 / 数字 / 布尔值function UserCard({ name, age, isVip }) {return (<div>{name} - {age} - {isVip ? VIP : 普通用户}</div>); }<UserCard name"张三" age{18} isVip{true} />✅ 2. 传递函数&…