对于Python下桌面软件的开发已经有了很多数据可视化的库,如Matplotlib、Seaborn、Pyqtgraph、Plotly等等,但这些库更适合于后端程序员的软件开发。
实际上在前端网页开发方面,也有很多很多漂亮的界面设计方案,也包括很多很多数据可视化方面的强大控件。基于此,我们是否可以考虑这样一种桌面软件的开发架构方案,即将前端技术融入到Python开发中,结合PyQt界面库,将前端网页界面无缝集成到PyQt的窗口中,大部分的功能依托于前端技术来实现,而PyQt仅作少部分辅助的诸如窗口生成、事件处理等工作,基于这样的架构进行桌面软件的开发,既能充分利用Python的快速开发优点,又能使用成熟的前端技术,应该是一个比较好的软件开发方案。
下面通过一个简单的例子来介绍这种方案的可行性,该例使用Python3语言,利用PyQ5界面库搭建界面窗口框架,然后在窗口中嵌入ECharts库进行数据的可视化。
这儿稍微简单介绍下ECharts库,它是一个使用 JAVAScript 实现的开源可视化库,可流畅的运行在 PC 和移动设备上,兼容当前绝大部分浏览器(IE8/9/10/11,Chrome,Firefox,Safari等),底层依赖矢量图形库 ZRender,提供直观,交互丰富,可高度个性化定制的数据可视化图表。它具有丰富的可视化类型, 提供了常规的折线图、柱状图、散点图、饼图、K线图,用于统计的盒形图,用于地理数据可视化的地图、热力图、线图,用于关系数据可视化的关系图、treemap、旭日图,多维数据可视化的平行坐标,还有用于 BI 的漏斗图,仪表盘,并且支持图与图之间的混搭等等。总之,ECharts库是一具非常强大的数据可视化库。
该例运行界面情况如下图所示:
使用PyQt5设计软件界面框架,主界面分为上下两部分,上面是一个Widget窗口控件,在里面嵌入网页通过一个柱状图显示某两个公司产品的全年季度销量趋势对比情况,下面加了两个按钮控件,分别控制启停数据的实时更新(使用仿真数据,仅为演示实时绘图刷新功能)及清除工作。
该例子的文件组成结构如下图所示:
整个工程放在webDemo文件夹中,其中,Main.py、Main.ico、Main.ui分别为主程序、应用程序图标及设计师设计的界面文件,Ui_Main.py为将Main.ui转换为Python后的文件,html文件夹存放了网页相关的文件。
大体设计思路如下:
在官网下载库文件echarts.min.js后,剩下的工作是写bar.html文件,其主要内容包括:引入ECharts界面库、定义显示区域大小、定义柱状图样式等等,其代码内容如下,比较好理解,添加了注释:
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<!-- 引入 echarts.min.js -->
<script src="echarts.min.js"></script>
<style type="text/css">
#main {height:100%; width:100%; position:absolute;}
body {margin:0px; padding:0px; overflow:hidden;}
</style>
</head>
<body>
<!-- 为ECharts准备一个具备大小(宽高)的Dom -->
<div id="main"></div>
<script type="text/JavaScript">
// 基于准备好的dom,初始化echarts实例
var myChart = echarts.init(document.getElementById('main'));
option = {
title: {
text: '全年季度销量趋势对比图',
left: 'center'
},
tooltip: {
show: true
},
legend: {
data: ['公司A', '公司B'],
top: '8%',
right: '10%'
},
xAxis: {
type: 'category',
data: ['第1季度', '第2季度', '第3季度', '第4季度'],
name: '季度 / x',
nameLocation: 'center',
nameGap: 30
},
yAxis: {
min: 0,
max: 100,
type: 'value',
name: '销量 / y',
nameLocation: 'center',
nameGap: 40
},
series: [
{
name: '公司A',
type: 'bar',
data: [0, 0, 0, 0]
},
{
name: '公司B',
type: 'bar',
data: [0, 0, 0, 0]
}
]
};
myChart.setOption(option);
function setValue(val1, val2){
option.series[0].data = val1
option.series[1].data = val2
myChart.setOption(option)
}
window.onresize = myChart.resize ;
</script>
</body>
</html>
注意,在上面代码中,定义了一个setValue函数,其目的是更新两条曲线的数据内容,其数据可由Python语言来调用时传入。
使用设计师设计的主界面Main.ui如下图所示,包含一个QWidget控件及两个按钮控件:
该界面中涉及到的所有界面对象元素如下图所示:
主界面设计完成后,即可用PyUIC工具将其转换为Py文件Ui_Main.py。
在主程序Main.py文件中,依托于设计师生成的界面文件,创建一个QWidget类用作主窗口的显示,其代码如下:
主要功能是定义主界面、加载网页文件及实现两个槽函数功能。通过“开始更新数据”按钮来启动或停止定时器函数,实现数据的实时刷新,通过“清空数据”按钮来清除柱状图数据。
主要代码解释如下:
第24-37行,使用QWebEngineView类定义一个webView视图,使用load函数加载网页文件bar.html,然后将其加入到上面的窗口布局中,注意,这儿仅程序初始化时加载了一次。
第39-42行,在定时器函数中刷新柱状图数据,主要是利用了webView页上的runJavaScript函数来运行html文件中的setValue函数,并将产生的两条随机数据传递到该函数中。
第44-52行,控制柱状图数据刷新的启动/停止动作。
第54-56行,通过传入全0数组,清空柱状图数据。
最终,整个主程序代码如下图所示:
至此,整个工程文件就全部完成了,运行程序后,就会出现开始的界面。通过这个例子可以看出,在Python语言中,结合PyQt库完全可以通过前端技术实现数据的可视化甚至界面的搭建,这对前端程序员开发桌面软件来说,无疑是一种比较好的方案。
本文由编码那些事原创,请关注+转发+收藏+点赞,带你一起长知识!