PyQt : 图表也能这么秀 ,无缝集成 ECharts

一. 前言

在这一篇里面会引入两个知识点 :

  • Apache ECharts : 一款 JavaScript 的可视化图表图 ,功能齐全 ,用法简单
  • PyQt6-WebEngine : PyQt6 的扩展模块,它基于 Qt WebEngine,允许在 PyQt6 应用程序中嵌入和显示现代网页内容

先来看一下 ECharts 支持的图表有多少

image.png

再来看看 WebEngine 的简单原理

WebEngine 是基于 Chromium 开发 ,通过集成 Chromium 到 QT 框架中 ,使 WebEngine 具有了浏览器的功能。

但是要注意 ,由于打入了 Chromium 的相关资源和文件 ,会导致 PyQt 导打包的文件明显变大。

所以在打包过程中 ,需要优化文件大小等工作(这个后续再看)。

二. PyQt 集成 Web-Engine

2.1 基础入门使用

// 安装 Web-WebEngine
pip install PyQt6 PyQt6-WebEngine


// 相关代码 : 
import sys
from PyQt6.QtWidgets import QApplication, QMainWindow
from PyQt6.QtWebEngineWidgets import QWebEngineView
from PyQt6.QtCore import QUrl

class WebBrowser(QMainWindow):
    def __init__(self):
        super().__init__()
        self.setWindowTitle('PyQt6 百度一下')
        self.setGeometry(100, 100, 1200, 800)

        
        self.browser = QWebEngineView()

        
        self.browser.setUrl(QUrl("https://www.baidu.com/"))

        
        self.setCentralWidget(self.browser)


if __name__ == "__main__":
    app = QApplication(sys.argv)
    window = WebBrowser()
    window.show()
    sys.exit(app.exec())

image.png

  • 在这个里面实现了基础的浏览器功能 ,让 PyQT 应用里面可以展示Web端的页面

直接展示 HTML 脚本


html_content = '''



    PyQt6 WebEngine Example


    

在 PyQt6 App 中展示一段 HTML 文本

'''
self.browser.setHtml(html_content)
  • 还可以通过传入一段 HTML 脚本 + setHtml 方法 ,展示 HTML 文本
  • 但是这样并不满足我们的复杂需求 ,我们需要一定的 JS 的能力

2.2 运行相关的 Java Script

第一种方式 : 把 JavaScript 代码写在脚本文件中

import sys
from PyQt6.QtWidgets import QApplication, QMainWindow, QPushButton, QVBoxLayout, QWidget
from PyQt6.QtWebEngineWidgets import QWebEngineView


class WebBrowser(QMainWindow):
    def __init__(self): 
        super().__init__()
        self.setWindowTitle('PyQt6 JS 代码')
        self.setGeometry(100, 100, 1200, 800)

        
        self.layout = QVBoxLayout()

        
        self.browser = QWebEngineView()

        
        html_content = '''
        
        
        
            JavaScript Example
        
        
            

这是一段文本!

'''
self.browser.setHtml(html_content) self.setCentralWidget(self.browser) // 省略 main 方法
  • 把 HTML 相关内容聚合在自己的 HTML 文件里面 ,然后让它的模块内部流转是 一种比较好的隔离方式
  • 但是 ,在 PyQT 上面我们无法进行完全的隔离 ,因为数据要进行流转 ,功能要回调 ,这样就要进行耦合交互

方式二 : Python 和 Web 交互进行耦合

import sys
from PyQt6.QtWidgets import QApplication, QMainWindow, QPushButton, QVBoxLayout, QWidget
from PyQt6.QtWebEngineWidgets import QWebEngineView


class WebBrowser(QMainWindow):
    def __init__(self):
        super().__init__()
        self.setWindowTitle('JavaScript 脚本的使用')
        self.setGeometry(100, 100, 1200, 800)

        
        self.layout = QVBoxLayout()

        
        self.browser = QWebEngineView()

        
        html_content = '''
        
        
        
            JavaScript Example
        
        
            

Hello, World!

'''
self.browser.setHtml(html_content) self.button = QPushButton('点击修改') self.button.clicked.connect(self.run_js) self.layout.addWidget(self.browser) self.layout.addWidget(self.button) container = QWidget() container.setLayout(self.layout) self.setCentralWidget(container) def run_js(self): self.browser.page().runJavaScript( 'document.getElementById("title").innerText="点了一下最下面的按钮"', self.js_callback) def js_callback(self, result): print(f"JavaScript Result: {result}") // 省略 main 方法

在这个代码里面 ,就实现了 PyQT 的工具组件和 JS / HTML 的交互关系

2.3 加载 HTML 文件

  • 不过 ,直接把 HTML 内容写在代码里面是很不合理的 ,所以可以通过引入 HTML 文件进行更轻量化的处理


current_dir = os.path.dirname(os.path.abspath(__file__))
local_file_path = os.path.join(current_dir, 'web.html')
local_url = QUrl.fromLocalFile(local_file_path)
self.browser.setUrl(local_url)


self.setCentralWidget(self.browser)
  • 这种方式也是比较理想的 HTML 集成方式

三. 集成 EChats

上面学习完了 WebEngine , 剩下就是 集成 Echats 了, 先来一个简易版的 :

基础简易版 :

image.png

代码就不贴了 ,我这里直接使用的本地JS文件 :

  • S1 : 下载 echats 的代码 Echats.main.js
  • S2 : 准备好 HTML 文件
  • S3 : 通过注入 HTML 的方式进行注入

从外部导入数据

image.png

❓ 为了让 Data 数据的导入更加方便 ,所以数据源要在 Python 代码中生成 ,并且导入到 HTML 文件中。

  • 由于 Echats 的良好支持 ,可以通过 JSON 文件进行数据的传递
  • 这里从一个 data.json 文件中读取到数据格式 ,通过 runJavaScript 运行 JS 脚本
  • 以下是完整代码 👇👇👇

import sys
import os
import json
from PyQt6.QtWidgets import QApplication, QMainWindow, QPushButton, QVBoxLayout, QWidget
from PyQt6.QtWebEngineWidgets import QWebEngineView
from PyQt6.QtCore import QUrl


class WebBrowser(QMainWindow):
    def __init__(self):
        super().__init__()
        self.setWindowTitle('PyQt6 WebEngine JavaScript Example')
        self.setGeometry(100, 100, 1200, 800)

        
        self.layout = QVBoxLayout()

        
        self.browser = QWebEngineView()

        
        current_dir = os.path.dirname(os.path.abspath(__file__))
        local_file_path = os.path.join(current_dir, 'no_data.html')
        url = QUrl.fromLocalFile(local_file_path)
        self.browser.setUrl(url)

        
        self.button = QPushButton('点击修改')
        self.button.clicked.connect(self.run_js)

        
        self.layout.addWidget(self.browser)
        self.layout.addWidget(self.button)

        
        container = QWidget()
        container.setLayout(self.layout)
        self.setCentralWidget(container)

    
    
    def run_js(self):
        
        data_str = self.load_json_data('data.json')
        print(f"JavaScript Result: {data_str}")
        js_code = f'initChart({data_str});'
        self.browser.page().runJavaScript(js_code)
    
    def js_callback(self, result):
        print(f"JavaScript Result: {result}")
    
    def load_json_data(self, filename):
        current_directory = os.path.dirname(os.path.abspath(__file__))
        json_file_path = os.path.join(current_directory, filename)
        with open(json_file_path, 'r', encoding='utf-8') as json_file:
            data = json.load(json_file)
        return data


if __name__ == "__main__":
    app = QApplication(sys.argv)
    window = WebBrowser()
    window.show()
    sys.exit(app.exec())



data.json + html

{
    "title": {
        "text": "ECharts 入门示例"
    },
    "tooltip": {},
    "legend": {
        "data": ["销量"]
    },
    "xAxis": {
        "data": ["衬衫", "羊毛衫", "雪纺衫", "裤子", "高跟鞋", "袜子"
        ]
    },
    "yAxis": {},
    "series": [
        {
        "name": "销量",
        "type": "bar",
        "data": [
                5,
                20,
                36,
                10,
                10,
                20
            ]
        }
    ]
}


html>
<html style="height: 100%">

<head>
    <meta charset="utf-8">
    <title>ECharts Exampletitle>
    
    <script src="echarts.min.js">script>
    <script type="text/javascript">
        if (typeof echarts === 'undefined') {
            alert('ECharts 加载失败');
        }
    script>
head>

<body style="height: 100%; margin: 0">
    <div id="main" style="height: 100%">div>

    <script type="text/javascript">
        function initChart(data) {
            
            myChart = echarts.init(document.getElementById('main'));
            myChart.setOption(data);
        }
    script>
body>

html>


  • 这里点击后 ,数据就自然生成了。👇👇👇
  • 复杂的操作就不展示了 ,能到这一步后面都唰唰唰的上

image.png

总结

使用感受 :

  • 论美观 ,JS 库还是要比 Python 的库强太多了
  • 上手难度不高 ,花1-2个小时就可以创建复杂的图表
  • 性能还不错 ,展示的很快 ,用法也很灵活

🎉🎉🎉❤️❤️❤️ 祝大家国庆节快乐 !!!

最后的最后 ❤️❤️❤️👇👇👇

阅读全文
下载说明:
1、本站所有资源均从互联网上收集整理而来,仅供学习交流之用,因此不包含技术服务请大家谅解!
2、本站不提供任何实质性的付费和支付资源,所有需要积分下载的资源均为网站运营赞助费用或者线下劳务费用!
3、本站所有资源仅用于学习及研究使用,您必须在下载后的24小时内删除所下载资源,切勿用于商业用途,否则由此引发的法律纠纷及连带责任本站和发布者概不承担!
4、本站站内提供的所有可下载资源,本站保证未做任何负面改动(不包含修复bug和完善功能等正面优化或二次开发),但本站不保证资源的准确性、安全性和完整性,用户下载后自行斟酌,我们以交流学习为目的,并不是所有的源码都100%无错或无bug!如有链接无法下载、失效或广告,请联系客服处理!
5、本站资源除标明原创外均来自网络整理,版权归原作者或本站特约原创作者所有,如侵犯到您的合法权益,请立即告知本站,本站将及时予与删除并致以最深的歉意!
6、如果您也有好的资源或教程,您可以投稿发布,成功分享后有站币奖励和额外收入!
7、如果您喜欢该资源,请支持官方正版资源,以得到更好的正版服务!
8、请您认真阅读上述内容,注册本站用户或下载本站资源即您同意上述内容!
原文链接:https://www.shuli.cc/?p=21012,转载请注明出处。
0

评论0

显示验证码
没有账号?注册  忘记密码?