20200511-01 基于 QCustomPlot 移植到 QML 上(qt.514)
源码下载
一:要点说明
1. replot() 界面刷新(需要单独调用)
replot() 这个函数的作用是用于刷新显示界面,根据文档显示,刷新的方式总共有 4 中:
rpImmediateRefresh 立即全局更新(先立即重绘表格,然后调用 QWidget::repaint() 重绘整个 widgetrpQueuedRefresh 依次更新(先立即重绘表格,然后调用 QWidget::update() 进行更新,避免多次 repaint() 消耗资源)rpRefreshHint (默认)取决于 hint 是否被设置为 QCP::phImmediaRefresh,可以查看 setPlottingHints)rpQueuedReplot 整个更新事件循环进行,以避免没有意义的重复更新
所以在作者使用中,采用 300ms 执行一次 replot(QCustomPlot::RefreshPriority::rpQueuedReplot) 进行界面更新
在测试中,IMX6UL, 500M CPU 资源占用率(不是特别高,没有单独计算仅在个人写的APP上为40-50之间波动)
2. 清除函数
似乎没有找到单独可以调用的函数,所以使用 setData() 函数代替
void clear_all(){//getPlot() 就是用来获取 QCustomPlot 指针getPlot()->graph(0)->setData(QVector<double>(), QVector<double>());getPlot()->replot();}
3. 单独加点
void append_data(const double& key, const double& val){getPlot()->graph(0)->addData(key, val);}
4. QQuickPaintItem
提供了在 QML 上绘制的 QPainter API,可以将 QWidget 或者自定义控件绘制到 QML 界面上,需要实现 paint() , 如果需要在控件上实现其他功能,比如鼠标功能,可以具体查看 QQuickItem 类中的虚拟函数定义
二:源码 (代码格式参考网上信息)
//ProFile
#需要添加
QT += quick qml printsupport core//main.cpp
QApplication app(argc, argv); //使用这个来代替 QCoreApplication 等默认创建的 application
qmlRegisterType <QCustomLine> ("DataModel", 1, 0, "ChartModel_Test");//main.qml
注意使用 ApplicationWindow{} 来代替 Window()
// qcustomchart.h
#include <QtQuick>class QCustomPlot;
class QCPAbstractPlottable;class QCustomChart : public QQuickPaintedItem
{
Q_OBJECT
public:
explicit QCustomChart(QQuickItem *parent = nullptr);
virtual ~QCustomChart();void paint(QPainter *painter) override;
virtual void initChartUI(){};QCustomPlot *getPlot();protected: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 onChartViewReplot();
void updateChartViewSize();
private: QCustomPlot* mCustomPlot {nullptr};
};//qcustomchart.cpp
#include "qcustomchart.h"
#include "qcustomplot.h"
#include <QDebug>QCustomChart::QCustomChart(QQuickItem *parent) : QQuickPaintedItem(parent),
mCustomPlot(new QCustomPlot())
{
setFlag(QQuickItem::ItemHasContents, true);
setAcceptedMouseButtons(Qt::AllButtons);
setAcceptHoverEvents(true);connect(this, &QQuickPaintedItem::widthChanged, this, &QCustomChart::updateChartViewSize);
connect(this, &QQuickPaintedItem::heightChanged, this, &QCustomChart::updateChartViewSize);}QCustomChart::~QCustomChart()
{
delete mCustomPlot;
}void QCustomChart::paint(QPainter *painter)
{
/// add active check
if (!painter->isActive())
return;
QPixmap picture( boundingRect().size().toSize() );
QCPPainter qcpPainter( &picture );
mCustomPlot->toPainter(&qcpPainter);
painter->drawPixmap(QPoint(), picture);
}QCustomPlot *QCustomChart::getPlot()
{
return mCustomPlot;
}void QCustomChart::mousePressEvent(QMouseEvent *event)
{
routeMouseEvents(event);
}void QCustomChart::mouseReleaseEvent(QMouseEvent *event)
{
routeMouseEvents(event);
}void QCustomChart::mouseMoveEvent(QMouseEvent *event)
{
routeMouseEvents(event);
}void QCustomChart::mouseDoubleClickEvent(QMouseEvent *event)
{
routeMouseEvents(event);
}void QCustomChart::wheelEvent(QWheelEvent *event)
{
routeWheelEvents( event );
}void QCustomChart::updateChartViewSize()
{
mCustomPlot->setGeometry(0, 0, (int)width(), (int)height());
mCustomPlot->setViewport(QRect(0, 0, (int)width(), (int)height()));
}void QCustomChart::onChartViewReplot()
{
update();
}void QCustomChart::routeMouseEvents(QMouseEvent *event)
{
QMouseEvent* newEvent = new QMouseEvent(event->type(), event->localPos(), event->button(), event->buttons(), event->modifiers());
QCoreApplication::postEvent(mCustomPlot, newEvent);
}void QCustomChart::routeWheelEvents(QWheelEvent *event)
{
QWheelEvent* newEvent = new QWheelEvent(event->pos(), event->delta(), event->buttons(), event->modifiers(), event->orientation());
QCoreApplication::postEvent(mCustomPlot, newEvent);
}
//qcustomline.h
#include "qcustomchart.h"class QCustomLine : public QCustomChart
{
Q_OBJECT
public:
explicit QCustomLine(QQuickItem *parent = nullptr);
virtual ~QCustomLine();
Q_INVOKABLE void initChart();Q_INVOKABLE void appendData(const double &key, const double &value);
Q_INVOKABLE void replace(const QVector<double> &keys, const QVector<double> &values);
Q_INVOKABLE void clearAll();
Q_INVOKABLE void setXYRange(int x_s, int x_e, int y_s, int y_e);
virtual void timerEvent(QTimerEvent *event) override;Q_INVOKABLE void append_test();
Q_INVOKABLE void replace_test();
Q_INVOKABLE void updateUI();};
//qcustomline.cpp
#include "qcustomline.h"
#include "qcustomplot.h"QCustomLine::QCustomLine(QQuickItem *parent) : QCustomChart(parent)
{}QCustomLine::~QCustomLine()
{}void QCustomLine::initChart()
{
updateChartViewSize();getPlot()->addGraph();
getPlot()->graph(0)->setPen( QPen(Qt::red));
getPlot()->xAxis->setLabel( "t1" );
getPlot()->yAxis->setLabel( "S1" );
getPlot()->xAxis->setRange( 0, 1000 );
getPlot()->yAxis->setRange( 0, 10 );
getPlot()->setInteractions( QCP::iRangeDrag | QCP::iRangeZoom );startTimer(1000);connect(getPlot(), &QCustomPlot::afterReplot, this, &QCustomLine::onChartViewReplot);// getPlot()->replot();
}void QCustomLine::appendData(const double &key, const double &value)
{
getPlot()->graph(0)->addData(key, value);
}void QCustomLine::replace(const QVector<double> &keys, const QVector<double> &values)
{
getPlot()->graph(0)->setData(keys, values);
getPlot()->replot();
}void QCustomLine::clearAll()
{
getPlot()->graph(0)->setData(QVector<double>(), QVector<double>());
getPlot()->replot();
}void QCustomLine::setXYRange(int x_s, int x_e, int y_s, int y_e)
{
getPlot()->xAxis->setRange(x_s, x_e);
getPlot()->yAxis->setRange(y_s, y_e);
getPlot()->replot();
}void QCustomLine::timerEvent(QTimerEvent */*event*/)
{
static double t, U;
U = ((double)rand() / RAND_MAX) * 5;
getPlot()->graph(0)->addData(t++, U);
getPlot()->replot();
}void QCustomLine::append_test()
{
static double t, U;
U = ((double)rand() / RAND_MAX) * 5;
appendData(t++, U);
}void QCustomLine::replace_test()
{
QVector<double> tX;
QVector<double> tY;
tX << 1 << 3 << 4;
tY << 1 << 5 << 1;
replace(tX, tY);
}void QCustomLine::updateUI()
{
getPlot()->replot(QCustomPlot::RefreshPriority::rpQueuedReplot);
}
异常记录:
1) 如下异常提示
如果出现这种异常提示:
QPainter::begin: Paint device returned engine = 0, type: 2
QPainter::setRenderHint: Painter must be active to set rendering hints
请检查,
一:QML 是否已经用 ApplicationWindow 代替 Window 控件
二:在使用中,作者是通过 loader 加载的控件,并且在启动之后默认调用了 replot() 根本原因在于时间差,paint device 并没有准备好,所以可以略微延时执行,在构造函数中不要调用 replot()
2)在嵌入式等资源受限设备中出现,异常不知原因内存溢出死机情况
很有可能是由于过快过多的图表刷新导致,内存资源耗尽导致程序嗝屁,建议跟新界面刷新策略,比如降低界面刷新的频率,去掉没有意义的界面刷新步骤
20200511-01 基于 QCustomPlot 移植到 QML 上(qt.514)相关推荐
- Linux浏览器libgtk-3,终于把WebKit(基于GTK)移植到ARM上
DirectFB用的命令是: ./configure -host=arm-linux --prefix=$ROOTFS_DIR/usr --with-gfxdrivers=none --enable- ...
- ARM硬件平台上基于UCOS移植Lwip网络协议栈
目录 1.硬件平台 1.1硬件平台简介 为保证网络协议栈的顺利移植,选用了LPC2220作为主控芯片,RTL8019AS作为网卡芯片,使用HR901170A进行电平转换.滤波. LPC2220是Phi ...
- 基于DE2的开源片上系统Freedom E310移植
引言:伯克利大学于2014年发布了开源指令集架构RISC-V,其目标是成为指令集架构领域的Linux,应用覆盖IoT(Internet of Things)设备.桌面计算机.高性能计算机等众多领域[1 ...
- 移植mysql到安卓手机_记录dbnet文本检测转ncnn并移植到安卓上
目前,文本检测主要分为基于检测网络和分割网络实现,上文(风影:记录densenet-ocr识别网络转ncnn并移植到安卓手机)讲到将yolo3文本检测+densenet识别网络转ncnn推理,并成功移 ...
- QT5系列教程二---基于qcustomplot的QT5 GUI串口收发绘图软件实现
QT5系列教程二---基于qcustomplot的QT5 GUI串口收发绘图软件实现 结构 UI部分 代码部分 step1:实现串口数据接受 串口接受数据格式 在`.pro`文件中添加`serialp ...
- ucos移植到stm32上的中断小小改进
uCosII移植到stm32上的文章和demo已经很多了,细节上建议大家可以看官方的移植文档( 当然是E文的).网上流传的各种移植版本基本都是基于官方的移植版本做了小改进.这些改进基本都限制在更适合自 ...
- Esp8266进阶之路16 esp8266的 基于Nonos移植红外线H1838,实现红外遥控器配网,远程控制一盏灯。(附带固件)
本系列博客学习由非官方人员 半颗心脏 潜心所力所写,不做开发板.仅仅做个人技术交流分享,不做任何商业用途.如有不对之处,请留言,本人及时更改. 序号 SDK版本 内容 链接 1 nonos2.0 搭建 ...
- 基于stm32f103c8t6移植uc/OS-III系统
文章目录 一.内容 二.uc/OS-III源码准备 三.使用 stm32CubeMX 建立工程 1)新建工程 2)工程配置 3)导出工程 四.项目准备 1)移植准备 2)文件移植 3)代码完善 4)参 ...
- 基于STM32F103移植华为LiteOS物联网系统
基于STM32F103移植华为LiteOS物联网系统 本实验是通过学习野火的<物联网操作系统 LiteOS开发实战指南>参考学习的. 1.移植前的准备 LiteOS 的源码可从 LiteO ...
最新文章
- 安装包制作工具 SetupFactory使用1 详解
- SASS初学者入门(转)
- string的内存管理问题
- 第二届360杯全国大学生信息安全技术大赛部分解题思路(逆向分析)
- 10个优秀的 Web UI 库/框架
- android ios logo原型,iOS关于logo和LaunchImage处理
- NewCode----求数列的和
- python 插补数据_python 2020中缺少数据插补技术的快速指南
- 程序员操作系统推荐_为什么程序员要会 Linux
- 风变python小课离线版_Python是个什么鬼?为什么医学生朋友圈里都是它!
- matlab jpeg 工具包,安装Matlab JPEG Toolbox
- PHP留言并展示_留言页面展示功能
- 【原创】一点点雕虫小技脚本
- zabbix item详解
- LG GPRO2 SudaMod 3.1 自编译版 20180524 更新
- 进化算法之粒子群算法介绍附代码——PSO
- 办公自动化oa按计算机分类,办公室自动化oa按计算机分类属于什么
- 《数据库与信息管理课程设计》
- Hadoop-day07(MapReduce三个小案例)
- 实现广告图片切换效果轮播图效果
热门文章
- python中输出手机话费_用Python生成柱状图、折线图、饼状图来统计自己的手机话费...
- 网络速率方面单位MBPS和MB的区别
- 2012年4月语言榜
- Entity Framework 6 Recipes 2nd Edition(9-7)译-在WCF服务中序列化代理
- GBase8S_RSS配置
- Win7 系统设置虚拟无线热点
- 将B站上下载的两个m4s文件合成为mp4文件
- 软件测试是否应该为软件质量背锅?
- 开源好物分享!文档在线预览平台
- 查询2021年甘肃高考成绩位次,2021年甘肃高考位次排名查询,甘肃高考位次所对应的学校...