QML WebEngine + ECharts展示实时曲线

(相信不少人都会用 ECharts 这个网页图表库,我这里也只是学 WebEngine 顺带做个笔记)

我的环境:Qt5.15.1 MSVC 32bit,不同的版本可能 webengine 的初始化有所不同,以官方文档为准。

本文完整项目链接:https://github.com/gongjianbo/MyTestCode/tree/master/Qml/QmlWebEngineECharts

0.下载ECharts

下载地址:https://echarts.apache.org/zh/download.html

提供了三种方式的下载:

方法一:从下载的源代码或编译产物安装

方法二:从 npm 安装

方法三:选择需要的模块,在线定制下载

这里我选择的定制下载:https://echarts.apache.org/zh/builder.html ,选择自己所需模块后就可以下载单个 js 文件。

1.QML WebEngine使用ECharts

WebEngine 初始化步骤参照文档:https://doc.qt.io/qt-5/qml-qtwebengine-webengineview.html

pro 文件加上 webengine 模块:

QT += webengine
   
   
     
     
     
     

main.cpp 文件初始化 webengine 相关:


   
   
     
     
     
     
  1. //#include
  2. // 因为5.13的在线文档没了,所以我没法判断,请自己查下文档
  3. #if (QT_VERSION >= QT_VERSION_CHECK(5,14,0))
  4. QCoreApplication:: setAttribute(Qt::AA_ShareOpenGLContexts);
  5. // 有些情况可能需要soft opengl
  6. QCoreApplication:: setAttribute(Qt::AA_UseSoftwareOpenGL);
  7. // webengine须初始化,5.12放在app构造后,5.15放在构造前
  8. QtWebEngine:: initialize();
  9. QGuiApplication app(argc, argv);
  10. #else
  11. // 5.12提示Attribute Qt::AA_ShareOpenGLContexts must be set before QCoreApplication is created
  12. QCoreApplication:: setAttribute(Qt::AA_ShareOpenGLContexts);
  13. // 有些情况可能需要soft opengl
  14. //QCoreApplication::setAttribute(Qt::AA_UseSoftwareOpenGL);
  15. // webengine须初始化,5.12放在app构造后,5.15放在构造前
  16. QGuiApplication app(argc, argv);
  17. QtWebEngine:: initialize();
  18. #endif

从 ECharts 的官方示例拷贝实时曲线的例程:https://echarts.apache.org/examples/zh/editor.html?c=dynamic-data2

QML WebEngine + ECharts展示实时曲线_第1张图片

将例程放到 html 文件中,参照:ECharts官方教程 ,由于比较长,我就放到下一节以及 github 链接了(我把 echarts.js 和 index.html 放在了单独的文件夹,pro DESTDIR 也指定到了该目录)。

最后把 qml 文件改改就能运行了:


   
   
     
     
     
     
  1. import QtQuick 2.12
  2. import QtQuick. Window 2.12
  3. import QtWebEngine 1.2
  4. Window {
  5. width: 640
  6. height: 480
  7. visible: true
  8. title: qsTr( "WebEngine + ECharts (By: GongJianBo1992)")
  9. WebEngineView{
  10. anchors. fill: parent
  11. //@disable-check M7
  12. url: "file:///./index.html"
  13. }
  14. }

尽量用 release 跑, debug 模式很容易崩溃。还有就是有些环境可能需要设置 AA_UseSoftwareOpenGL 才能正常运行,但是这又导致持续动态刷新很占 cpu。

2.传递数据到 html ,实时刷新曲线

webengine 传递数据到 html 还是比较方便的,可以直接调用 js 函数传递参数,也可以用 websocket,或者 ajax 请求数据。这里我使用的调用 js 函数传递 JSON 参数。

webengineview 提供了 runJavaScript 函数在 web 中执行脚本:

void runJavaScript(string script, variant callback)
   
   
     
     
     
     

最终效果:

QML WebEngine + ECharts展示实时曲线_第2张图片

下面是 html 和 qml 的代码:

完整项目链接:https://github.com/gongjianbo/MyTestCode/tree/master/Qml/QmlWebEngineECharts


   
   
     
     
     
     
  1. import QtQuick 2.12
  2. import QtQuick. Window 2.12
  3. import QtQuick. Controls 2.12
  4. import QtWebEngine 1.2
  5. Window {
  6. id: root
  7. width: 640
  8. height: 480
  9. visible: true
  10. title: qsTr( "WebEngine + ECharts (By: GongJianBo1992)")
  11. property var now: new Date( 1997, 9, 3)
  12. property var oneDay: 24 * 3600 * 1000
  13. WebEngineView{
  14. id: view
  15. anchors. fill: parent
  16. //@disable-check M7
  17. url: "file:///./index.html"
  18. }
  19. Row{
  20. anchors. right: parent. right
  21. anchors. top: parent. top
  22. anchors. margins: 10
  23. spacing: 10
  24. Button{
  25. text: "单个数据"
  26. onClicked: {
  27. now = new Date(+now + oneDay);
  28. view. runJavaScript( "window.appendData("+
  29. JSON. stringify({
  30. "date":now. valueOf(),
  31. "value": Number( Math. random() * 1000 + 500)
  32. })+ ")");
  33. }
  34. }
  35. Button{
  36. text: "批量数据"
  37. onClicked: {
  38. let datalist=[];
  39. for( let i= 0;i< 100;i++)
  40. {
  41. now = new Date(+now + oneDay);
  42. datalist. push({ "date":now. valueOf(), "value": Number( Math. random() * 1000 + 500)});
  43. }
  44. view. runJavaScript( "window.setData("+
  45. JSON. stringify(datalist)+ ")");
  46. }
  47. }
  48. }
  49. }

   
   
     
     
     
     
  1. html>
  2. <html lang="en">
  3. <head>
  4. <meta charset="UTF-8">
  5. <meta name="viewport" content="width=device-width, initial-scale=1.0">
  6. <title>Document title>
  7. <style>
  8. html,
  9. body,
  10. #echarts {
  11. margin: 0px;
  12. padding: 0px;
  13. width: 100%;
  14. height: 100%;
  15. }
  16. style>
  17. head>
  18. <body>
  19. <div id="echarts"> div>
  20. <script src="./echarts.min.js"> script>
  21. <script>
  22. //每次now+一天
  23. function randomData( ) {
  24. now = new Date(+now + oneDay);
  25. //name给标签用,value是x-y坐标点
  26. return {
  27. name: now. toString(),
  28. value: [now, Math. random() * 1000 + 500]
  29. };
  30. }
  31. //新的数据
  32. function newData( dataitem) {
  33. now = new Date(dataitem. date);
  34. return {
  35. name: now. toString(),
  36. value: [now, dataitem. value]
  37. };
  38. }
  39. var myChart = echarts. init( document. getElementById( 'echarts'));
  40. var data = [];
  41. var now = + new Date( 1970, 1, 1);
  42. var oneDay = 24 * 3600 * 1000;
  43. myChart. setOption({
  44. title: {
  45. text: '动态数据 + 时间坐标轴'
  46. },
  47. tooltip: {
  48. trigger: 'axis',
  49. formatter: function ( params) {
  50. params = params[ 0];
  51. var date = new Date(params. name);
  52. return date. getDate() + '/' + (date. getMonth() + 1) + '/' + date. getFullYear() + ' : ' +
  53. params. value[ 1];
  54. },
  55. axisPointer: {
  56. animation: false
  57. }
  58. },
  59. xAxis: {
  60. type: 'time',
  61. min: now - 100 * oneDay,
  62. max: now,
  63. splitLine: {
  64. show: false
  65. }
  66. },
  67. yAxis: {
  68. type: 'value',
  69. min: 0,
  70. max: 2000,
  71. boundaryGap: [ 0, '100%'],
  72. splitLine: {
  73. show: false
  74. }
  75. },
  76. series: [{
  77. name: '模拟数据',
  78. type: 'line',
  79. showSymbol: false,
  80. hoverAnimation: false,
  81. data: data
  82. }]
  83. });
  84. //刷新数据
  85. function updateData( ) {
  86. myChart. setOption({
  87. xAxis: {
  88. type: 'time',
  89. min: now - 100 * oneDay,
  90. max: now
  91. },
  92. series: [{
  93. data: data
  94. }]
  95. });
  96. }
  97. //定时填充数据
  98. //每次数据x加一天,范围为100天
  99. /*setInterval(function () {
  100. if (data.length > 100)
  101. data.shift();
  102. data.push(randomData());
  103. updateData();
  104. }, 200);*/
  105. //我们定义dataitem结构为[date,value]
  106. //添加单个数据
  107. function appendData( dataitem) {
  108. if (data. length > 100)
  109. data. shift();
  110. data. push( newData(dataitem));
  111. updateData();
  112. }
  113. //添加批量数据
  114. function setData( datalist) {
  115. if (datalist. length <= 0)
  116. return;
  117. while (datalist. length > 100)
  118. datalist. shift();
  119. data = [];
  120. for ( var i = 0; i < datalist. length; i++)
  121. data. push( newData(datalist[i]));
  122. updateData();
  123. }
  124. //自适应大小
  125. window. addEventListener( "resize", function ( ) {
  126. myChart. resize();
  127. });
  128. script>
  129. body>
  130. html>

 

你可能感兴趣的:(QT/C++,1024程序员节)