若该文为原创文章,转载请注明原文出处
本文章博客地址:https://hpzwl.blog.csdn.net/article/details/125731144
红胖子(红模仿)的博文大全:开发技术集合(包含Qt实用技术、树莓派、三维、OpenCV、OpenGL、ffmpeg、OSG、单片机、软硬结合等等)持续更新中…(点击传送门)
上一篇:《Qt+ECharts开发笔记(二):Qt窗口动态调整大小,使ECharts跟随Qt窗口大小变换而变换大小》
下一篇:敬请期待…
上一篇成功是EChart随着Qt窗口变化而变化,本篇将开始正式介绍柱状图介绍、基础使用,并将其封装一层Qt。
本篇的demo实现了隐藏js代码的方式,实现了一个条形图的基本交互方式,即Qt调用js脚本操作html。

ECharts提供的纯JS代码编辑开发调试工具,可编辑js,并且查看运行效果:
https://echarts.apache.org/examples/zh/editor.html

开发过程中对于属性的查询和调试ECharts也提供了配置帮助。
官方配置手册:https://echarts.apache.org/zh/option.html

随便找一个预期目标:

使用EChart调试工具开发,先调试出基础框架。
这里贴出的全部代码:
ECharts
动态方式,最初目的是为了动态实现数据的js操作,在开发过程中发现动态方式还能隐藏echarts代码,使echarts代码不被抓取,最后决定全部改为动态加载方式。
ECharts
新增了loadFinished信号槽关联。
void BarEChartWidget::initControl()
{
_pWebEngineView = new QWebEngineView(this);
_pWebEnginePage = new QWebEnginePage(this);
_pWebChannel = new QWebChannel(this);
QString filePath;
#if 1
filePath = QString("%1/%2").arg(_htmlDir).arg(_indexFileName);
#else
filePath = "qrc:/barEChartWidget/html/barEChartWidget.html";
#endif
LOG << "file exist:" << QFile::exists(filePath) << filePath;
#if 0
// 打印html文件内容
QFile file(_indexFilePath);
file.open(QIODevice::ReadOnly);
LOG << QString(file.readAll());
file.close();
#endif
connect(_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::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);
}
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脚本。
html文件
ECharts
在代码中使用js初始化echarts:
BarECartWidget.h
#ifndef BARECHARTWIDGET_H
#define BARECHARTWIDGET_H
#include
#include
#include
#include
namespace Ui {
class BarEChartWidget;
}
class BarEChartWidget : public QWidget
{
Q_OBJECT
public:
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
#include
#include
// QtCreator在msvc下设置编码也或有一些乱码,直接一刀切,避免繁琐的设置
//#define MSVC
#ifdef MSVC
#define QSTRING(s) QString::fromLocal8Bit(s)
#else
#define QSTRING(s) QString(s)
#endif
#include
#include
//#define LOG qDebug()<<__FILE__<<__LINE__
//#define LOG qDebug()<<__FILE__<<__LINE__<<__FUNCTION__
//#define LOG qDebug()<<__FILE__<<__LINE__<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);
#endif
initControl();
}
BarEChartWidget::~BarEChartWidget()
{
delete ui;
}
void BarEChartWidget::initControl()
{
_pWebEngineView = new QWebEngineView(this);
_pWebEnginePage = new QWebEnginePage(this);
_pWebChannel = new QWebChannel(this);
QString filePath;
#if 1
filePath = QString("%1/%2").arg(_htmlDir).arg(_indexFileName);
#else
filePath = "qrc:/barEChartWidget/html/barEChartWidget.html";
#endif
LOG << "file exist:" << QFile::exists(filePath) << filePath;
#if 0
// 打印html文件内容
QFile file(_indexFilePath);
file.open(QIODevice::ReadOnly);
LOG << QString(file.readAll());
file.close();
#endif
connect(_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();
}
通过qt代码跑js调用函数失败。


先要等页面加载完成后才能调用定义的函数。
发现是调用成功了,原来只定义也会报这个错误。

由此可以看出,在qt中去初始化需要等待页面加载完成才行。
少数中文乱码,加空格等都无法解决。

最终解决了,尝试了QTextCodec等各种都不行,最终:



条形图将会根据实际需求持续升级版本,下一篇会继续折线图的基础封装。
上一篇:《Qt+ECharts开发笔记(二):Qt窗口动态调整大小,使ECharts跟随Qt窗口大小变换而变换大小》
下一篇:敬请期待…
若该文为原创文章,转载请注明原文出处
本文章博客地址:https://hpzwl.blog.csdn.net/article/details/125731144
先自我介绍一下,小编13年上师交大毕业,曾经在小公司待过,去过华为OPPO等大厂,18年进入阿里,直到现在。深知大多数初中级java工程师,想要升技能,往往是需要自己摸索成长或是报班学习,但对于培训机构动则近万元的学费,着实压力不小。自己不成体系的自学效率很低又漫长,而且容易碰到天花板技术停止不前。因此我收集了一份《java开发全套学习资料》送给大家,初衷也很简单,就是希望帮助到想自学又不知道该从何学起的朋友,同时减轻大家的负担。添加下方名片,即可获取全套学习资料哦