首頁  >  文章  >  後端開發  >  Python小技之不用 Gui,照樣實現圖形介面

Python小技之不用 Gui,照樣實現圖形介面

PHPz
PHPz轉載
2023-04-12 16:43:071602瀏覽

如果說程式設計師有什麼怕的,那我想可能就是— 需求又變了!

這不,客戶在筆者開發完一個基於瀏覽器的Web 應用程式之後說:程序需要在內(無)部(網)環境中運行…

這就意味著無法安裝Python 環境!

誰叫咱是程式設計師呢,不就開發一個GUI 版本嗎,難不倒我…

可是聽到給的時間後,就不淡定了…

為了不影響客戶的評測,只能給一週時間!

構思

GUI 雖然也不難,不過需要梳理一遍服務以及與用戶的交互接口,弄不好就得為GUI 單獨編寫接口,這點時間顯然不夠呀。

不行,就再想想辦法…

不然直接將Web 應用包裝成一個可執行程序,拷貝到機器上就能運行,而且類似的框架很多,比如Nodejs 中的Electron[1],Python 中的Pywebview[2]。

只要包裝原來的Web 程式就好了,那麼說乾就乾!

神器出場

Web 程式是用Flask 開發的,所以需要安裝Python的Pywebview 作為打包工具。

建立虛擬環境[3] 或在原始的Web 專案環境中,執行:

pip install pywebview

在Windows 系統中,需要.Net 4.0 以上

小試牛刀:

import webview

window = webview.create_window('Hello!', 'http://http://www.justdopython.com')
webview.start()
  • 引用webview 庫
  • 啟動一個窗口,設定標題為Hello!,指定頁面位址
  • 啟動webview
##就能看到如下的效果:

Python小技之不用 Gui,照樣實現圖形介面

小試牛刀

#神奇吧!

Pywebview 支援三種模式,簡單模式,伺服器模式和線程模式。

簡單模式 就相當於一個自訂串流瀏覽器,指定一個位址,就可以實現瀏覽了,如上面的例子。

伺服器模式 相當於包裝了一個 Web 應用,就是會啟動一個本機伺服器,在客製化的瀏覽器中瀏覽。

線程模式 比較高級,就是需要自己手動維護線程狀態,實現更高級的玩法。

對於現在的需求,我們選擇伺服器模式,也就是包裝本地的一個 Web 應用。

對接 Flask

伺服器模式會提供我們一個 HTTP Server,只要把 Web 應用程式部署上去就好了。

因為無非展示實際專案的程式碼,這裡寫一個簡單的Flask 應用:

關於Flask Web 應用開發,可以參考筆者之前寫的Flask 文章

建立一個app.py 檔案:

from flask import Flask, render_template, jsonify, request

app = Flask(__name__) # 创建一个应用

@app.route('/') 
def index():# 定义根目录处理器
return render_template('index.html')

@app.route('/detail')
def detail():
return render_template('detail.html') 

if __name__ == '__main__':
app.run() # 启动服务

這個應用程式很簡單,只有兩個頁面,分別透過/ 和/detail 來存取。

如果經營這段程式碼,就會啟動一個 Flask 應用,透過 http://120.0.0.1:5000 來存取。

如何套在Pywebview 中呢?

很簡單:

import webview
from app import app

if __name__ == '__main__':
window = webview.create_window('Pywebview', app, height=600, width=1000)
webview.start()

    引入webview
  • ##引入剛才所建立的app
  • #建立一個webview window,並將app 作為url 參數傳入
  • 然後啟動webview 就可以了
  • 這裡的關鍵是,將Flask 應用作為url 參數,Webview 發現傳入的參數是flask 應用,就會啟動服務模式。

執行程式後,可以看到和在瀏覽器中的效果一樣的:

Python小技之不用 Gui,照樣實現圖形介面#對接Flask

##目錄問題

現在就可以將這個專案打包成exe 了。

首先需要安裝pyinstaller[4]

pip install pyinstaller

然後進入程式目錄執行:

pyinstall -F -w main.py

F 參數表示將程式打包成一個可執行文件,不加這個參數就會打包成一個資料夾夾

    w 參數表示執行打包好的可執行程式時,不顯示命令列窗口,這個特性只有在Windows 系統中有
  • #很快在程式目錄下,就會產生一個dist 資料夾,其中就會有一個main.exe 可執行文件,這就是打包好的結果。
雙擊運行,可以看到效果…

等等,好像並不是想像中的那樣!

##對接Flask

Python小技之不用 Gui,照樣實現圖形介面這是怎麼回事呢?

根據提示來看,是因為找不到頁面的範本檔案。

我們在前面建立Flask app 時,使用的是預設的範本路徑,也就是app.py 檔案所在目錄的templates 目錄,為啥打包之後就找不見了呢?

這是因為在windows 中,可執行檔的運行時,會被解壓縮到一個特定的目錄下,而我們的模板檔並沒有被打包進入exe 檔中,所以導致運行時找不見模板檔。

完美呈现

如何解决这个问题呢?

作为不使用外部数据或文件的程序,只需要将程序本身打包就可以了,但大部分程序都需要外部数据,比如我们的 Flask 应用,就需要用到静态文件等。

那么如何将它们打包进可执行文件呢?

只需要在打包时多加一个参数就可以了:

pyinstaller main.py -F -w --add-data "./templates/*;templates"

-- add-data 参数表示添加额外的数据 -- ./templates/* 表示需要添加当前目录的 templates 目录中的所有文件 -- ;为分隔符,其后的 templates 表示解压是这些数据所在的目录,这个目录名必须和 创建 app 时 template_folder 参数一致 -- 如果需要用到静态文件,需要额外添加,比如 --add-data "./static/*;static"

这样就能将外部数据一起打包进来了。

打包好后,双击执行,就会发现网页得以完美呈现了。

注意:

如果使用了虚拟环境,必须在虚拟环境中单独安装 pyinstaller,而不能用其他环境中已经安装好的,这是为了包装打包是可以链接所以程序引用的模块

因为 pyinstaller 打包时,找不到被引用的模块时并不报错,而打包好的程序可能会无法执行。

总结

经过一番折腾,终于在客户要求的时间之前将工作完成了,特别高兴。

回头一想,多亏用了 Python 作为主要的开发语言,因为 Python 强悍的社区支持没有找不到的解决方法。

这次经历的另一个启示就是,遇到问题,不要着急就做,可以先想一想,是否有更好的方法,特别在使用 Python 的时候。

比心!

参考代码

​https://www.php.cn/link/0c52d419a421fb13bb58357e67b7fb4b​

[1]Electron: https://www.electronjs.org/

[2]Pywebview: https://pywebview.flowrl.com/

[3]虚拟环境: https://mp.weixin.qq.com/s/WflK5pOKhvPg8zrf_W5mfw

[4]pyinstaller: https://pyinstaller.readthedocs.io/en/stable/


以上是Python小技之不用 Gui,照樣實現圖形介面的詳細內容。更多資訊請關注PHP中文網其他相關文章!

陳述:
本文轉載於:51cto.com。如有侵權,請聯絡admin@php.cn刪除