Qt+ECharts开发笔记(三):ECharts的柱状图介绍、基础使用和Qt封装Demo
若该文为原创文章,转载请注明原文出处
本文章博客地址:https://hpzwl.blog.csdn.net/article/details/125731144
红胖子(红模仿)的博文大全:开发技术集合(包含Qt实用技术、树莓派、三维、OpenCV、OpenGL、ffmpeg、OSG、单片机、软硬结合等等)持续更新中…(点击传送门)
Qt开发专栏:三方库开发技术
前言
上一篇成功是EChart随着Qt窗口变化而变化,本篇将开始正式介绍柱状图介绍、基础使用,并将其封装一层Qt。
本篇的demo实现了隐藏js代码的方式,实现了一个条形图的基本交互方式,即Qt调用js脚本操作html。
Demo演示
ECharts调试工具
ECharts提供的纯JS代码编辑开发调试工具,可编辑js,并且查看运行效果:
https://echarts.apache.org/examples/zh/editor.html
开发过程中对于属性的查询和调试ECharts也提供了配置帮助。
官方配置手册:https://echarts.apache.org/zh/option.html
目标
随便找一个预期目标:
ECharts接口静态方式
使用EChart调试工具开发,先调试出基础框架。
这里贴出的全部代码:
<!DOCTYPE html>
<html><head><meta charset="utf-8" /><title>ECharts</title><!-- 引入刚刚下载的 ECharts 文件 --><!--<script src="echarts.js"></script>--><script src="./echarts.js"></script><!--<script src="D:/qtProject/echartsDemo/echartsDemo/modules/barEChartWidget/html/echarts.js"></script>--><!--<script src="echarts.min.js"></script>--><!--<script src="./echarts.min.js"></script>--><!--<script src="./html/echarts.min.js"></script>--><!--<script src="D:/qtProject/echartsDemo/echartsDemo/modules/barEChartWidget/html/echarts.min.js"></script>--></head><body><!--设置body跟随查u哪个口,main填充body--><style>#main,html,body{width: 100%;height: 100%;overflow: hidden;}#main {width: 100%;height: 100%;}</style><div id="main"></div><script type="text/javascript">// 基于准备好的dom,初始化echarts实例var myChart = echarts.init(document.getElementById('main'));// 窗口高度变化设置window.onresize = function() {myChart.resize();};// 指定图表的配置项和数据var option = {title: {text: 'ECharts 入门示例'},tooltip: {},legend: {data: ['销量']},xAxis: {data: ['衬衫', '羊毛衫', '雪纺衫', '裤子', '高跟鞋', '袜子']},yAxis: {},series: [{name: '销量',type: 'bar',data: [5, 20, 36, 10, 10, 20]}]};// 使用刚指定的配置项和数据显示图表。myChart.setOption(option);function initJs() {var myChart = echarts.init(document.getElementById('main'));var option;option = {tooltip: {trigger: 'axis'},grid: {left: '3%',right: '4%',bottom: '50',containLabel: true},legend: {orient: 'horizontal',x: 'center',y: 'bottom',itemGap: 100},xAxis: {type: 'value'},yAxis: {type: 'category',data: ['项目1', '项目2', '项目3']},series: [{name: '变量1',type: 'bar',stack: 'totla',label: {show: true},data: [11, 12, 13]},{name: '子项目1',type: 'bar',stack: 'totla',label: {show: true},data: [24, 20, 21]},{name: '变量3',type: 'bar',stack: 'totla',label: {show: true},data: [95, 87, 55]}]};};initJs();</script></body>
</html>
ECharts接口动态方式
动态方式,最初目的是为了动态实现数据的js操作,在开发过程中发现动态方式还能隐藏echarts代码,使echarts代码不被抓取,最后决定全部改为动态加载方式。
步骤一:修改html
<!DOCTYPE html>
<html><head><meta charset="utf-8" /><title>ECharts</title><script src="./echarts.js"></script></head><body><style>#main,html,body{width: 100%;height: 100%;overflow: hidden;}#main {width: 95%;height: 95%;}</style><div id="main"></div><script type="text/javascript">var myChart = echarts.init(document.getElementById('main'));window.onresize = function() {myChart.resize();};</script></body>
</html>
步骤二:初始化
新增了loadFinished信号槽关联。
void BarEChartWidget::initControl()
{_pWebEngineView = new QWebEngineView(this);_pWebEnginePage = new QWebEnginePage(this);_pWebChannel = new QWebChannel(this);QString filePath;
#if 1filePath = QString("%1/%2").arg(_htmlDir).arg(_indexFileName);
#elsefilePath = "qrc:/barEChartWidget/html/barEChartWidget.html";
#endifLOG << "file exist:" << QFile::exists(filePath) << filePath;
#if 0// 打印html文件内容QFile file(_indexFilePath);file.open(QIODevice::ReadOnly);LOG << QString(file.readAll());file.close();
#endifconnect(_pWebEnginePage, SIGNAL(loadFinished(bool)), this, SLOT(slot_loadFinished(bool)));_pWebEnginePage->load(QUrl(filePath));_pWebEnginePage->setWebChannel(_pWebChannel);_pWebEngineView->setPage(_pWebEnginePage);// 背景透明
// _pWebEngineView->setStyleSheet("background-color: transparent");_pWebEnginePage->setBackgroundColor(Qt::transparent);
}
步骤三:加载完成页面后进行初始化
void BarEChartWidget::slot_loadFinished(bool result)
{if(result){initJs();}
}
void BarEChartWidget::initJs()
{_initJsStr = QSTRING("var option;""option = {"" tooltip: {"" trigger: 'axis'"" },"" grid: {"" left: '10',"" right: '10',"" top: '10',"" bottom: 30,"" containLabel: true"" },"" legend: {"" orient: 'horizontal',"" x: 'center',"" y: 'bottom',"" itemGap: 20"" },"" xAxis: {"" type: 'value'"" },"" yAxis: {"" type: 'category',"" data: ['项目1', '项目2', '项目3']"" },"" series: ["" {"" name: '变量1',"" type: 'bar',"" stack: 'totla',"" label: {"" show: true"" },"" data: [11, 12, 13]"" },"" {"" name: '变量2',"" type: 'bar',"" stack: 'totla',"" label: {"" show: true"" },"" data: [24, 20, 21]"" },"" {"" name: '变量3',"" type: 'bar',"" stack: 'totla',"" label: {"" show: true"" },"" data: [95, 87, 55]"" }"" ]""};""myChart.setOption(option);");runJsScript(_initJsStr);
}void BarEChartWidget::runJsScript(QString str)
{if(_pWebEnginePage){_pWebEnginePage->runJavaScript(str);}
}
步骤四:动态执行js操作
重置
void BarEChartWidget::on_pushButton_reset_clicked()
{initJs();
}
刷新
void BarEChartWidget::on_pushButton_flush_clicked()
{QString jsStr ="var empty = {};""myChart.setOption(empty, true);""myChart.setOption(option, true);";runJsScript(jsStr);
}
清空
void BarEChartWidget::on_pushButton_clear_clicked()
{QString jsStr ="option.series[0].data = [];""option.series[1].data = [];""option.series[2].data = [];""myChart.setOption(option, true);";runJsScript(jsStr);
}
随机生成(使用js代码)
void BarEChartWidget::on_pushButton_createRandom_clicked()
{QString jsStr ="var min = 0;""var max = 100;""for(var i = 0; i < option.series.length; i++)""{"" for(var j = 0; j < option.yAxis.data.length; j++)"" {"" option.series[i].data[j] = Math.floor(Math.random() * (max - min)) + min;"" }""}""myChart.setOption(option, true);";runJsScript(jsStr);
}
后续用会将数据进行Qt的一份缓存数据,由Qt的数据去生成ecahrts的js脚本。
Demo
html文件
<!DOCTYPE html>
<html><head><meta charset="utf-8" /><title>ECharts</title><script src="./echarts.js"></script></head><body><style>#main,html,body{width: 100%;height: 100%;overflow: hidden;}#main {width: 95%;height: 95%;}</style><div id="main"></div><script type="text/javascript">var myChart = echarts.init(document.getElementById('main'));window.onresize = function() {myChart.resize();};</script></body>
</html>
在代码中使用js初始化echarts:
BarECartWidget.h
#ifndef BARECHARTWIDGET_H
#define BARECHARTWIDGET_H#include <QWidget>
#include <QWebEngineView>
#include <QWebEnginePage>
#include <QWebChannel>namespace Ui {class BarEChartWidget;
}class BarEChartWidget : public QWidget
{Q_OBJECTpublic:explicit BarEChartWidget(QWidget *parent = 0);~BarEChartWidget();protected:void initControl();protected slots:void slot_loadFinished(bool result);protected:void initJs();protected:void runJsScript(QString str);protected:void resizeEvent(QResizeEvent *event);private slots:void on_pushButton_clear_clicked();void on_pushButton_flush_clicked();void on_pushButton_createRandom_clicked();void on_pushButton_reset_clicked();private:Ui::BarEChartWidget *ui;private:QWebEngineView *_pWebEngineView; // 浏览器窗口QWebEnginePage *_pWebEnginePage; // 浏览器页面QWebChannel *_pWebChannel; // 浏览器js交互QString _htmlDir; // html文件夹路径QString _indexFileName; // html文件QString _initJsStr; // 第一次初始化的表格
};#endif // BARECHARTWIDGET_H
BarEChartWidget.cpp
#include "BarEChartWidget.h"
#include "ui_BarEChartWidget.h"#include <QFile>
#include <QMessageBox>
#include <QTimer>// QtCreator在msvc下设置编码也或有一些乱码,直接一刀切,避免繁琐的设置
//#define MSVC
#ifdef MSVC
#define QSTRING(s) QString::fromLocal8Bit(s)
#else
#define QSTRING(s) QString(s)
#endif#include <QDebug>
#include <QDateTime>
//#define LOG qDebug()<<__FILE__<<__LINE__
//#define LOG qDebug()<<__FILE__<<__LINE__<<__FUNCTION__
//#define LOG qDebug()<<__FILE__<<__LINE__<<QThread()::currentThread()
//#define LOG qDebug()<<__FILE__<<__LINE__<<QDateTime::currentDateTime().toString("yyyy-MM-dd")
#define LOG qDebug()<<__FILE__<<__LINE__<<QDateTime::currentDateTime().toString("yyyy-MM-dd hh:mm:ss:zzz")BarEChartWidget::BarEChartWidget(QWidget *parent) :QWidget(parent),ui(new Ui::BarEChartWidget),_pWebEngineView(0),_pWebEnginePage(0),_pWebChannel(0),_htmlDir("D:/qtProject/echartsDemo/echartsDemo/modules/barEChartWidget/html"), // 使用了绝对路径,引到html文件夹_indexFileName("barEChartWidget.html")
{ui->setupUi(this);QString version = "v1.0.0";setWindowTitle(QString("基于Qt的ECharts条状图Demo %1(长沙红胖子 QQ:21497936 WX:15173255813 blog:hpzwl.blog.csdn.net").arg(version));// 设置无边框,以及背景透明// 背景透明,在界面构架时,若为本窗口为其他窗口提升为本窗口时,// 则再qss会在主窗口第一级添加frame_all,防止其他窗口提升本窗口而冲掉qss设置
// setWindowFlag(Qt::FramelessWindowHint);
// setAttribute(Qt::WA_TranslucentBackground, true);#if 0// 这是方法一:让滚动条不出来(通过大小),还有一个方法是在html设置body的overflow: hidden
// resize(600 + 20, 400 + 20);
#endifinitControl();
}BarEChartWidget::~BarEChartWidget()
{delete ui;
}void BarEChartWidget::initControl()
{_pWebEngineView = new QWebEngineView(this);_pWebEnginePage = new QWebEnginePage(this);_pWebChannel = new QWebChannel(this);QString filePath;
#if 1filePath = QString("%1/%2").arg(_htmlDir).arg(_indexFileName);
#elsefilePath = "qrc:/barEChartWidget/html/barEChartWidget.html";
#endifLOG << "file exist:" << QFile::exists(filePath) << filePath;
#if 0// 打印html文件内容QFile file(_indexFilePath);file.open(QIODevice::ReadOnly);LOG << QString(file.readAll());file.close();
#endifconnect(_pWebEnginePage, SIGNAL(loadFinished(bool)), this, SLOT(slot_loadFinished(bool)));_pWebEnginePage->load(QUrl(filePath));_pWebEnginePage->setWebChannel(_pWebChannel);_pWebEngineView->setPage(_pWebEnginePage);// 背景透明
// _pWebEngineView->setStyleSheet("background-color: transparent");_pWebEnginePage->setBackgroundColor(Qt::transparent);
}void BarEChartWidget::slot_loadFinished(bool result)
{if(result){initJs();}
}void BarEChartWidget::initJs()
{_initJsStr = QSTRING("var option;""option = {"" tooltip: {"" trigger: 'axis'"" },"" grid: {"" left: '10',"" right: '10',"" top: '10',"" bottom: 30,"" containLabel: true"" },"" legend: {"" orient: 'horizontal',"" x: 'center',"" y: 'bottom',"" itemGap: 20"" },"" xAxis: {"" type: 'value'"" },"" yAxis: {"" type: 'category',"" data: ['项目1', '项目2', '项目3']"" },"" series: ["" {"" name: '变量1',"" type: 'bar',"" stack: 'totla',"" label: {"" show: true"" },"" data: [11, 12, 13]"" },"" {"" name: '变量2',"" type: 'bar',"" stack: 'totla',"" label: {"" show: true"" },"" data: [24, 20, 21]"" },"" {"" name: '变量3',"" type: 'bar',"" stack: 'totla',"" label: {"" show: true"" },"" data: [95, 87, 55]"" }"" ]""};""myChart.setOption(option);");runJsScript(_initJsStr);
}void BarEChartWidget::runJsScript(QString str)
{if(_pWebEnginePage){_pWebEnginePage->runJavaScript(str);}
}void BarEChartWidget::resizeEvent(QResizeEvent *event)
{if(_pWebEngineView){_pWebEngineView->setGeometry(ui->label_echarts->geometry());}
}void BarEChartWidget::on_pushButton_clear_clicked()
{QString jsStr ="option.series[0].data = [];""option.series[1].data = [];""option.series[2].data = [];""myChart.setOption(option, true);";runJsScript(jsStr);
}void BarEChartWidget::on_pushButton_flush_clicked()
{QString jsStr ="var empty = {};""myChart.setOption(empty, true);""myChart.setOption(option, true);";runJsScript(jsStr);
}void BarEChartWidget::on_pushButton_createRandom_clicked()
{QString jsStr ="var min = 0;""var max = 100;""for(var i = 0; i < option.series.length; i++)""{"" for(var j = 0; j < option.yAxis.data.length; j++)"" {"" option.series[i].data[j] = Math.floor(Math.random() * (max - min)) + min;"" }""}""myChart.setOption(option, true);";runJsScript(jsStr);
}void BarEChartWidget::on_pushButton_reset_clicked()
{initJs();
}
入坑
入坑一:调用js函数失败
问题
通过qt代码跑js调用函数失败。
原理
先要等页面加载完成后才能调用定义的函数。
解决
发现是调用成功了,原来只定义也会报这个错误。
由此可以看出,在qt中去初始化需要等待页面加载完成才行。
入坑二:Qt的msvc编译器少数中文乱码
问题
少数中文乱码,加空格等都无法解决。
解决
最终解决了,尝试了QTextCodec等各种都不行,最终:
工程模板v1.2.0
后话
条形图将会根据实际需求持续升级版本,下一篇会介绍饼图的基本使用以及Qt封装的百分比饼图Demo。
上一篇:《Qt+ECharts开发笔记(二):Qt窗口动态调整大小,使ECharts跟随Qt窗口大小变换而变换大小》
下一篇:《Qt+ECharts开发笔记(四):ECharts的饼图介绍、基础使用和Qt封装百分比图Demo》
若该文为原创文章,转载请注明原文出处
本文章博客地址:https://hpzwl.blog.csdn.net/article/details/125731144
Qt+ECharts开发笔记(三):ECharts的柱状图介绍、基础使用和Qt封装Demo相关推荐
- Qt+ECharts开发笔记(五):ECharts的动态排序柱状图介绍、基础使用和Qt封装Demo
若该文为原创文章,转载请注明原文出处 本文章博客地址:https://hpzwl.blog.csdn.net/article/details/127171413 红胖子(红模仿)的博文大全:开发技术集 ...
- 开发笔记——vue echarts图表在切换页面大小时缩成一团
开发笔记--vue echarts图表在切换页面大小时缩成一团 添加this.$nextTick() this.$nextTick(()=>{this.getjkechertsdata(); / ...
- Qt+QtWebApp开发笔记(一):QtWebApp介绍、下载和搭建基础封装http轻量级服务器Demo
若该文为原创文章,转载请注明原文出处 本文章博客地址:https://hpzwl.blog.csdn.net/article/details/130631547 红胖子网络科技博文大全:开发技术集合( ...
- vue3中,echarts使用(四)02——柱状图之堆叠条形图-定制化 封装切换tag标签组件 封装title组件
vue3中,echarts使用(四)02--柱状图之堆叠条形图-定制化 & 封装切换tag标签组件 & 封装title组件 效果 代码 1.主页面 index.vue <temp ...
- 【Visual C++】游戏开发笔记三十七 浅墨DirectX提高班之五 顶点缓存的红颜知己 索引缓存的故事
分享一下我老师大神的人工智能教程!零基础,通俗易懂!http://blog.csdn.net/jiangjunshow 也欢迎大家转载本篇文章.分享知识,造福人民,实现我们中华民族伟大复兴! 本系列文 ...
- 【Visual C++】游戏开发笔记三十七 浅墨DirectX提高班之五 顶点缓存的红颜知己:索引缓存的故事
本系列文章由zhmxy555(毛星云)编写,转载请注明出处. 文章链接: http://blog.csdn.net/zhmxy555/article/details/8304741 作者:毛星云(浅墨 ...
- 【Vue ECharts开发】自定义echarts柱状图颜色渐变效果
1. 效果演示 2. 示例代码 Vue 模板代码: <template><div><div id="main"></div>< ...
- 麒麟系统开发笔记(二):国产麒麟系统搭建Qt开发环境安装Qt5.12
若该文为原创文章,转载请注明原文出处 本文章博客地址:https://hpzwl.blog.csdn.net/article/details/123840699 红胖子(红模仿)的博文大全:开发技术集 ...
- JNI开发笔记(三)--JNI工程的框架分析
JNI工程的框架分析 引 1. JNI工程的组成部分 2. 各个部分之间的关系 引 JNI开发笔记(一)–Android Studio安装与环境搭建 JNI开发笔记(二)–创建JNI基础工程并运行 1 ...
- 【Visual C++】游戏开发笔记三十四 浅墨DirectX提高班之三 起承转合的艺术:Direct3D渲染五步曲...
本系列文章由zhmxy555(毛星云)编写,转载请注明出处. 文章链接: http://blog.csdn.net/zhmxy555/article/details/8223965 作者:毛星云(浅墨 ...
最新文章
- MySQL数据库性能优化之一
- 刘涵 美国 西北大学 计算机,西北大学关于表彰2010-2011学年度学生先进集体-红帆.doc...
- Apache+php5
- Standard Template Library标准模板库专项复习总结(一)
- java 实例的生命周期_[Java教程]Vue实例生命周期
- 床笠行业调研报告 - 市场现状分析与发展前景预测(2021-2027年)
- activemq高可用
- java 事件处理机制
- JS编程练习题(javascript)
- 修改电脑微信提示音+dll文件编辑器
- 4r照片尺寸是多大_4寸照片尺寸多少厘米 多少像素
- 机器学习:概念学习FIND-S算法C++实现
- 在Android上模拟登录广工正方教务系统查询成绩
- [完全版] Windows安装与配置Git cz (commitizen)
- 观察 | 经济学诺奖的启示:金融科技的核心任务是什么?
- m个苹果放在n个筐里,每个筐至少一个,所有的筐都一样,有多少种放法
- 第九节-python函数介绍(中)
- 服务器原装的系统怎么格式化,怎么将云服务器系统格式化
- 员工被提拔,还是被干掉,就看这3点......
- 年末放大招,Java进阶大数据3W全套视频免费领!
热门文章
- 使用Javascript动态添加和删除元素
- 电脑上怎么批量压缩图片?如何快速批量压缩图片?
- 塔米狗上的达人名片有什么作用?
- Gossip 协议详解
- 【操作系统】CPU调度算法
- 小鸡模拟器显示无法连接服务器,小鸡模拟器安装不了怎么办
- C++ atuo关键字的应用 -- 尾置返回类型(trailing return type)
- 华为p9总显示切换服务器中,怎么更改华为p9的多任务切换 | 手游网游页游攻略大全...
- Qt之小学徒学习记录分享
- 不需要死记硬背,看一遍就能记住单词的意思,一起了解单词背后的有趣故事(6)