若该文为原创文章,转载请注明原文出处
本文章博客地址:https://hpzwl.blog.csdn.net/article/details/127171413
红胖子(红模仿)的博文大全:开发技术集合(包含Qt实用技术、树莓派、三维、OpenCV、OpenGL、ffmpeg、OSG、单片机、软硬结合等等)持续更新中…(点击传送门)
Qt开发专栏:三方库开发技术
上一篇:《Qt+ECharts开发笔记(四):ECharts的饼图介绍、基础使用和Qt封装百分比图Demo》
下一篇:敬请期待…
前言
上一篇的demo使用隐藏js代码的方式,实现了一个饼图的基本交互方式,并预留了Qt模块对外的基础接口。
本篇的demo实现了自动排序的柱状图,实现了一个自动排序柱状图的基本交互方式,即Qt调用js脚本操作html。
本篇demo使用Qt定时器方式,实现数据定时刷新自增,并预留出了定时器间隔参数。
像大数据网页常看的人口增长时间图,收入年度增长时间图等都是这一类。
Demo演示
ECharts代码效果调试
使用ECharts的在线调试器,先调试出大致预期的效果。
option ={xAxis:{max:'dataMax'},yAxis:{type:'category',data:['特斯拉','奔驰','宝马','理想','蔚来'],inverse:true,animationDuration:300,animationDurationUpdate:300,max:4},series:[{realtimeSort:true,name:'X',type:'bar',data:[10,20,50,10,30],label:{show:true,position:'right',valueAnimation:true},itemStyle:{color:function(params){var colorList =['#EE14FF','#F092FF','#FF61FE','#A02F99','#F00682'];/* 注意1:需要分号 */return colorList[params.dataIndex];/* 注意2:需要dataIndex,获取序号 */}}},],graphic:{elements:[/* 时间标志 */{type:'text',right:160,bottom:100,style:{text:'1970-01',font:'bolder 100px monospace',fill:'rgba(100, 100, 100, 0.25)'},z:100}]},legend:{show:false,},animationDuration:0,animationDurationUpdate:1000,animationEasing:'linear',animationEasingUpdate:'linear'};
Qt封装动态ECharts
步骤一:静态html
此系列的标准html文件,因为是标准的所以对文件名进行了调整,改为eChartWidget.html。
<!DOCTYPEhtml><html><head><metacharset="utf-8"/><title>ECharts</title><scriptsrc="./echarts.js"></script></head><body><style>#main,
html,
body{width: 100%;height: 100%;overflow: hidden;}#main{width: 95%;height: 95%;}</style><divid="main"></div><scripttype="text/javascript">var myChart = echarts.init(document.getElementById('main'));
window.onresize=function(){
myChart.resize();};</script></body></html>
步骤二:初始化
voidBarAutoSortEChartWidget::initControl(){
_pWebEngineView =newQWebEngineView(this);
_pWebEnginePage =newQWebEnginePage(this);
_pWebChannel =newQWebChannel(this);
QString filePath;#if1
filePath =QString("%1/%2").arg(_htmlDir).arg(_indexFileName);#else
filePath ="qrc:/barAutoSortEChartWidget/html/eChartWidget.html";#endif
LOG <<"file exist:"<<QFile::exists(filePath)<< filePath;#if0// 打印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);}
步骤三:动态操作
重置
voidBarAutoSortEChartWidget::on_pushButton_reset_clicked(){initJs();}
刷新
voidBarAutoSortEChartWidget::on_pushButton_flush_clicked(){
QString jsStr ="var empty = {};""myChart.setOption(empty, true);""myChart.setOption(option, true);";runJsScript(jsStr);}
开始统计(使用Qt代码)
这里预留了定时器间隔。
voidBarAutoSortEChartWidget::on_pushButton_start_clicked(){if(_timerId ==-1){
LOG << ui->lineEdit_interval->text().toInt();
_timerId =startTimer(ui->lineEdit_interval->text().toInt());
_dateTime.setSecsSinceEpoch(0);
QString jsStr =QString("option.series[0].data[0] = 0;""option.series[0].data[1] = 0;""option.series[0].data[2] = 0;""option.series[0].data[3] = 0;""option.series[0].data[4] = 0;""option.graphic.elements[0].style.text= '%1';""myChart.setOption(option, true);").arg(_dateTime.toString("yyyy-MM"));runJsScript(jsStr);
ui->pushButton_start->setText("停止统计");}else{if(_timerId !=-1){killTimer(_timerId);
_timerId =-1;}
ui->pushButton_start->setText("开始统计");}}voidBarAutoSortEChartWidget::timerEvent(QTimerEvent *event){
_dateTime = _dateTime.addMonths(1);if(_dateTime >=QDateTime::currentDateTime()){if(_timerId !=-1){killTimer(_timerId);
_timerId =-1;}}
QString jsStr =QString("option.series[0].data[0] = option.series[0].data[0] + %1;""option.series[0].data[1] = option.series[0].data[1] + %2;""option.series[0].data[2] = option.series[0].data[2] + %3;""option.series[0].data[3] = option.series[0].data[3] + %4;""option.series[0].data[4] = option.series[0].data[4] + %5;""option.graphic.elements[0].style.text= '%6';""myChart.setOption(option, true);").arg(qrand()%100).arg(qrand()%100).arg(qrand()%100).arg(qrand()%100).arg(qrand()%100).arg(_dateTime.toString("yyyy-MM"));runJsScript(jsStr);}
清除数据
voidBarAutoSortEChartWidget::on_pushButton_clear_clicked(){
_dateTime.setSecsSinceEpoch(0);
QString jsStr =QString("option.series[0].data[0] = 0;""option.series[0].data[1] = 0;""option.series[0].data[2] = 0;""option.series[0].data[3] = 0;""option.series[0].data[4] = 0;""option.graphic.elements[0].style.text= '%1';""myChart.setOption(option, true);").arg(_dateTime.toString("yyyy-MM"));runJsScript(jsStr);}
Demo源码
BarAutoSortEChartWidget.h
#ifndefBARAUTOSORTECHARTWIDGET_H#defineBARAUTOSORTECHARTWIDGET_H#include<QWidget>#include<QWebEngineView>#include<QWebEnginePage>#include<QWebChannel>namespace Ui {classBarAutoSortEChartWidget;}classBarAutoSortEChartWidget:publicQWidget{
Q_OBJECT
public:explicitBarAutoSortEChartWidget(QWidget *parent =0);~BarAutoSortEChartWidget();protected:voidinitControl();protected slots:voidslot_loadFinished(bool result);protected:voidinitJs();protected:voidrunJsScript(QString str);protected:voidresizeEvent(QResizeEvent *event);voidtimerEvent(QTimerEvent *event);private slots:voidon_pushButton_clear_clicked();voidon_pushButton_flush_clicked();voidon_pushButton_start_clicked();voidon_pushButton_reset_clicked();private:
Ui::BarAutoSortEChartWidget *ui;private:
QWebEngineView *_pWebEngineView;// 浏览器窗口
QWebEnginePage *_pWebEnginePage;// 浏览器页面
QWebChannel *_pWebChannel;// 浏览器js交互
QString _htmlDir;// html文件夹路径
QString _indexFileName;// html文件
QString _initJsStr;// 第一次初始化的表格private:int _timerId;
QDateTime _dateTime;};#endif// BARAUTOSORTECHARTWIDGET_H
BarAutoSortEChartWidget.cpp
#include"BarAutoSortEChartWidget.h"#include"ui_BarAutoSortEChartWidget.h"#include<QFile>#include<QMessageBox>#include<QTimer>// QtCreator在msvc下设置编码也或有一些乱码,直接一刀切,避免繁琐的设置//#define MSVC#ifdefMSVC#defineQSTRING(s)QString::fromLocal8Bit(s)#else#defineQSTRING(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")#defineLOGqDebug()<<__FILE__<<__LINE__<<QDateTime::currentDateTime().toString("yyyy-MM-dd hh:mm:ss:zzz")BarAutoSortEChartWidget::BarAutoSortEChartWidget(QWidget *parent):QWidget(parent),ui(new Ui::BarAutoSortEChartWidget),_pWebEngineView(0),_pWebEnginePage(0),_pWebChannel(0),_htmlDir("D:/qtProject/echartsDemo/echartsDemo/modules/barAutoSortEChartWidget/html"),// 使用了绝对路径,引到html文件夹_indexFileName("eChartWidget.html"),_timerId(-1){
ui->setupUi(this);
QString version ="v1.0.0";setWindowTitle(QString("基于Qt的ECharts条状图(自动排序)Demo %1(长沙红胖子).arg(version));// 设置无边框,以及背景透明// 背景透明,在界面构架时,若为本窗口为其他窗口提升为本窗口时,// 则再qss会在主窗口第一级添加frame_all,防止其他窗口提升本窗口而冲掉qss设置// setWindowFlag(Qt::FramelessWindowHint);// setAttribute(Qt::WA_TranslucentBackground, true);#if0// 这是方法一:让滚动条不出来(通过大小),还有一个方法是在html设置body的overflow: hidden// resize(600 + 20, 400 + 20);#endifinitControl();}BarAutoSortEChartWidget::~BarAutoSortEChartWidget(){delete ui;}voidBarAutoSortEChartWidget::initControl(){
_pWebEngineView =newQWebEngineView(this);
_pWebEnginePage =newQWebEnginePage(this);
_pWebChannel =newQWebChannel(this);
QString filePath;#if1
filePath =QString("%1/%2").arg(_htmlDir).arg(_indexFileName);#else
filePath ="qrc:/barAutoSortEChartWidget/html/eChartWidget.html";#endif
LOG <<"file exist:"<<QFile::exists(filePath)<< filePath;#if0// 打印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);}voidBarAutoSortEChartWidget::slot_loadFinished(bool result){if(result){initJs();// 因为使用布局,在没有完全构造之前,其大小是不可预期的,等构造完成后,布局的大小才会形成,此时再初始化一次resizeEvent(0);}}voidBarAutoSortEChartWidget::initJs(){
_initJsStr =QSTRING("option = {"" xAxis: {"" max: 'dataMax'"" },"" yAxis: {"" type: 'category',"" data: ['特斯拉', '奔驰', '宝马', '理想', '蔚来'],"" inverse: true,"" animationDuration: 300,"" animationDurationUpdate: 300,"" max: 4"" },"" series: ["" {"" realtimeSort: true,"" name: 'X',"" type: 'bar',"" data: [10,20,50,10,30],"" label: {"" show: true,"" position: 'right',"" valueAnimation: true"" },"" itemStyle: {"" color: function(params) {"" var colorList = ['#EE14FF', '#F092FF', '#FF61FE', '#A02F99', '#F00682']; /* 注意1:需要分号 */"" return colorList[params.dataIndex]; /* 注意2:需要dataIndex,获取序号 */"" }"" }"" },"" ],"" graphic: {"" elements: [ /* 时间标志 */"" {"" type: 'text', "" right: 160,"" bottom: 100,"" style: {"" text: '1970-01',"" font: 'bolder 100px monospace',"" fill: 'rgba(100, 100, 100, 0.25)'"" },"" z: 100"" }"" ]"" },"" legend: {"" show: false,"" },"" animationDuration: 0,"" animationDurationUpdate: 1000,"" animationEasing: 'linear',"" animationEasingUpdate: 'linear'""};""myChart.setOption(option);");runJsScript(_initJsStr);}voidBarAutoSortEChartWidget::runJsScript(QString str){if(_pWebEnginePage){
_pWebEnginePage->runJavaScript(str);}}voidBarAutoSortEChartWidget::resizeEvent(QResizeEvent *event){if(_pWebEngineView){
_pWebEngineView->setGeometry(ui->label_echarts->geometry());
LOG << ui->label_echarts->geometry();}}voidBarAutoSortEChartWidget::timerEvent(QTimerEvent *event){
_dateTime = _dateTime.addMonths(1);if(_dateTime >=QDateTime::currentDateTime()){if(_timerId !=-1){killTimer(_timerId);
_timerId =-1;}}
QString jsStr =QString("option.series[0].data[0] = option.series[0].data[0] + %1;""option.series[0].data[1] = option.series[0].data[1] + %2;""option.series[0].data[2] = option.series[0].data[2] + %3;""option.series[0].data[3] = option.series[0].data[3] + %4;""option.series[0].data[4] = option.series[0].data[4] + %5;""option.graphic.elements[0].style.text= '%6';""myChart.setOption(option, true);").arg(qrand()%100).arg(qrand()%100).arg(qrand()%100).arg(qrand()%100).arg(qrand()%100).arg(_dateTime.toString("yyyy-MM"));runJsScript(jsStr);}voidBarAutoSortEChartWidget::on_pushButton_clear_clicked(){
_dateTime.setSecsSinceEpoch(0);
QString jsStr =QString("option.series[0].data[0] = 0;""option.series[0].data[1] = 0;""option.series[0].data[2] = 0;""option.series[0].data[3] = 0;""option.series[0].data[4] = 0;""option.graphic.elements[0].style.text= '%1';""myChart.setOption(option, true);").arg(_dateTime.toString("yyyy-MM"));runJsScript(jsStr);}voidBarAutoSortEChartWidget::on_pushButton_flush_clicked(){
QString jsStr ="var empty = {};""myChart.setOption(empty, true);""myChart.setOption(option, true);";runJsScript(jsStr);}voidBarAutoSortEChartWidget::on_pushButton_start_clicked(){if(_timerId ==-1){
LOG << ui->lineEdit_interval->text().toInt();
_timerId =startTimer(ui->lineEdit_interval->text().toInt());
_dateTime.setSecsSinceEpoch(0);
QString jsStr =QString("option.series[0].data[0] = 0;""option.series[0].data[1] = 0;""option.series[0].data[2] = 0;""option.series[0].data[3] = 0;""option.series[0].data[4] = 0;""option.graphic.elements[0].style.text= '%1';""myChart.setOption(option, true);").arg(_dateTime.toString("yyyy-MM"));runJsScript(jsStr);
ui->pushButton_start->setText("停止统计");}else{if(_timerId !=-1){killTimer(_timerId);
_timerId =-1;}
ui->pushButton_start->setText("开始统计");}}voidBarAutoSortEChartWidget::on_pushButton_reset_clicked(){initJs();}
工程模板v1.4.0
入坑
入坑一:排序图问题无法自动排序
问题
没有排序:
原理
这里之前我们已经遇见各种坑了,所以直接上调试工具,将Qt的js初始化代码在调试工具当中跑,如下图,web调试网页效果:
解决方法
自己调整序号,交换数据可以实现,但是无法实现上下条交换的动画了。
上一篇:《Qt+ECharts开发笔记(四):ECharts的饼图介绍、基础使用和Qt封装百分比图Demo》
下一篇:敬请期待…
若该文为原创文章,转载请注明原文出处
本文章博客地址:https://hpzwl.blog.csdn.net/article/details/127171413
版权归原作者 长沙红胖子Qt 所有, 如有侵权,请联系我们删除。