引言
對于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的庫文件,這兒使用的是echarts.min.js,編寫柱狀圖網頁文件bar.html;
- 主界面設計:用設計師設計程序主界面文件Main.ui,并將其轉換為對應的.py文件,即Ui_Main.py;
- 主程序功能實現:編寫主Python程序Main.py,搭建界面,嵌入網頁并實現槽函數功能。
前端文件準備
在官網下載庫文件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庫完全可以通過前端技術實現數據的可視化甚至界面的搭建,這對前端程序員開發桌面軟件來說,無疑是一種比較好的方案。
本文由編碼那些事原創,請關注+轉發+收藏+點贊,帶你一起長知識!