Qt+ECharts開發筆記(一):ECharts介紹、下載和Qt呼叫ECharts基礎柱狀圖Demo

21497936發表於2022-07-04

前言

  使用Qt開發大資料視覺化看板,基於Qt使用QWidget或者QML是很難達到ECharts大資料看板的效果,所以使用Qt來製作。

核心思想

  每一個ECharts圖表使用一個無邊框的QWebView來展示,這樣多個不同型別的ECharts圖表就是多個封裝不同型別ECharts圖表的QWebView(html載入入QWebView視窗來實現),每一個模組封裝的資料用qt預留介面呼叫js程式碼實現修改html的功能,最終達到程式碼操作qt即可操作圖表的功能。

Demo演示

   在這裡插入圖片描述
  為了實現我們多模組化,視窗的背景透明是很關鍵的,測試背景透明:
   在這裡插入圖片描述
  提升視窗背景透明效果:
   在這裡插入圖片描述
  測試結果可以達到預期。

ECharts

簡介

  ECharts,縮寫來自 Enterprise Charts,商業級資料圖表,是百度的一個開源的資料視覺化工具,一個純 Javascript 的圖表庫,能夠在 PC 端和移動裝置上流暢執行,相容當前絕大部分瀏覽器(IE6/7/8/9/10/11,chrome,firefox,Safari等),底層依賴輕量級的 Canvas 庫 ZRender,ECharts 提供直觀,生動,可互動,可高度個性化定製的資料視覺化圖表。創新的拖拽重計算、資料檢視、值域漫遊等特性大大增強了使用者體驗,賦予了使用者對資料進行挖掘、整合的能力。

主要功能

  ECharts 提供了常規的折線圖、柱狀圖、散點圖、餅圖、K線圖,用於統計的盒形圖,用於地理資料視覺化的地圖、熱力圖、線圖,用於關係資料視覺化的關係圖、treemap、旭日圖,多維資料視覺化的平行座標,還有用於 BI 的漏斗圖,儀表盤,並且支援圖與圖之間的混搭。

下載

  官網地址:echarts.apache.org
  線上定製:echarts.apache.org/zh/builder.html
  一個一個封裝,所以僅勾選柱狀圖
   在這裡插入圖片描述
   在這裡插入圖片描述
  經過等待:
   在這裡插入圖片描述
  然後會卡住,卡住的原因是因為勾選了“相容IE8”,所以補勾選久可,請耐心等下,最後會下載一個js,如下圖:
   在這裡插入圖片描述
   在這裡插入圖片描述
  那麼直接使用全部下下來的吧,3.5MB左右,並不是很大,後續如果細化釋出再看使用到了什麼去定製什麼。

Qt中引入ECharts

步驟一:引入web模組

  這個很關鍵,在Qt5.6以後使用了谷歌瀏覽器核心,不再支援mingw32版本的,所以要使用msvc版本的Qt。
   在這裡插入圖片描述
  msvc遇到了錯誤,參照《 關於 Qt編譯時使用msvc編譯器報錯“Error: cannot open …main.obj.10836.32.jom for write” 的解決方法》解決。

QT += webenginewidgets

步驟二:初始化視窗

  建構函式中,置0

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呼叫EChartsDemo %1(長沙紅胖子 QQ:21497936 WX:15173255813 blog:hpzwl.blog.csdn.net").arg(version));
    // 設定無邊框,以及背景透明
    // 背景透明,在介面構架時,若為本視窗為其他視窗提升為本視窗時,
    // 則再qss會在主視窗第一級新增frame_all,防止其他視窗提升本視窗而沖掉qss設定//    setWindowFlag(Qt::FramelessWindowHint);
    setAttribute(Qt::WA_TranslucentBackground, true);
    // 讓捲軸不出來
    resize(600 + 20, 400 + 20);
    initControl();}

  一個是瀏覽器視窗初始化,一個是js互動的初始化

void BarEChartWidget::initControl(){
    _pWebEngineView = new QWebEngineView(this);
    _pWebEnginePage = new QWebEnginePage(this);
    _pWebChannel = new QWebChannel(this);
    QString filePath;#if 0
    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
    _pWebEnginePage->load(QUrl(filePath));
    _pWebEnginePage->setWebChannel(_pWebChannel);
    _pWebEngineView->setPage(_pWebEnginePage);
    // 背景透明//    _pWebEngineView->setStyleSheet("background-color: transparent");//    _pWebEnginePage->setBackgroundColor(Qt::transparent);}

步驟三:視窗大小跟隨

void BarEChartWidget::resizeEvent(QResizeEvent *event){
    if(_pWebEngineView)
    {
        _pWebEngineView->setGeometry(rect());
    }}

模組化

  這是柱狀圖模組。
   在這裡插入圖片描述

Demo

BarEChartWidget.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:
    void resizeEvent(QResizeEvent *event);private:
    Ui::BarEChartWidget *ui;private:
    QWebEngineView *_pWebEngineView;            // 瀏覽器視窗
    QWebEnginePage *_pWebEnginePage;            // 瀏覽器頁面
    QWebChannel *_pWebChannel;                  // 瀏覽器js互動
    QString _htmlDir;                           // html資料夾路徑
    QString _indexFileName;                     // html檔案};#endif // BARECHARTWIDGET_H

BarEChartsWidget.cpp

#include "BarEChartWidget.h"#include "ui_BarEChartWidget.h"#include <QFile>#include <QMessageBox>// 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呼叫EChartsDemo %1(長沙紅胖子 QQ:21497936 WX:15173255813 blog:hpzwl.blog.csdn.net").arg(version));
    // 設定無邊框,以及背景透明
    // 背景透明,在介面構架時,若為本視窗為其他視窗提升為本視窗時,
    // 則再qss會在主視窗第一級新增frame_all,防止其他視窗提升本視窗而沖掉qss設定//    setWindowFlag(Qt::FramelessWindowHint);
    setAttribute(Qt::WA_TranslucentBackground, true);
    // 讓捲軸不出來
    resize(600 + 20, 400 + 20);
    initControl();}BarEChartWidget::~BarEChartWidget(){
    delete ui;}void BarEChartWidget::initControl(){
    _pWebEngineView = new QWebEngineView(this);
    _pWebEnginePage = new QWebEnginePage(this);
    _pWebChannel = new QWebChannel(this);
    QString filePath;#if 0
    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
    _pWebEnginePage->load(QUrl(filePath));
    _pWebEnginePage->setWebChannel(_pWebChannel);
    _pWebEngineView->setPage(_pWebEnginePage);
    // 背景透明//    _pWebEngineView->setStyleSheet("background-color: transparent");//    _pWebEnginePage->setBackgroundColor(Qt::transparent);}void BarEChartWidget::resizeEvent(QResizeEvent *event){
    if(_pWebEngineView)
    {
        _pWebEngineView->setGeometry(rect());
    }}

barEChartWidget.html

<!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>
    <!-- 為 ECharts 準備一個定義了寬高的 DOM -->
    <div id="main" style="width:600px; height:400px;"></div>
    <script type="text/javascript">
        // 基於準備好的dom,初始化echarts例項
        const myChart = echarts.init(document.getElementById('main'));
        // 指定圖表的配置項和資料
        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);
    </script>
  </body></html>

工程模板v1.0.0

   在這裡插入圖片描述

入坑

入坑一:“js: Uncaught TypeError: echarts.init is not a function”錯誤

問題

   在這裡插入圖片描述
   在這裡插入圖片描述
    在這裡插入圖片描述
  各種測試都不行:
   在這裡插入圖片描述

解決方法

  echarts的版本5.x太高,換成低版本的4.x就解決了
  
  成功載入: 在這裡插入圖片描述


來自 “ ITPUB部落格 ” ,連結:http://blog.itpub.net/70010283/viewspace-2904095/,如需轉載,請註明出處,否則將追究法律責任。

相關文章