python的gui太難用了,唯一能配置獨立前端的程序只有web。所以用web做前端,到python,完美!
環境准備
Python 3.9
Chrome瀏覽器(由於Eel是直接調用的Chrome的app啟動模式,所以自己很輕量,不過需要提前安裝有Chrome)
安裝Eel庫
pip install eel
文件結構
├── main.py 主入口
├── venv virtualenv環境
└── web 靜態文件
├── css
├── favicon.ico
├── img
└── main.html
上面web文件夾用來存放各種靜態文件,我是直接用的CDN上的css和js庫,比用npm裝到本地還省事兒。
這里主要提一下favicon.ico這個文件,以前擼html從來沒做過這個圖標,在Eel中這個文件將會顯示為程序左上角的圖標,所以還是挑個好看點的扔進來吧。
main.py
import eel # 定義html文件所在文件夾名稱 eel.init('web') @eel.expose # 使用裝飾器,類似flask里面對路由的定義 def py_fun(a): content = '你好!' + a return(content) # 測試調用js中的函數,同樣需要使用回調函數 js_return = eel.js_fun('python傳過去的參數')(lambda x: print(x)) # 啟動的函數調用放在最后,port=0表示使用隨機端口,size=(寬,高) eel.start('main.html', port=0, size=(600,300))
main.html
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <meta name="viewport" content="width=device-width, initial-scale=1.0"> <meta http-equiv="X-UA-Compatible" content="ie=edge"> <title>Eel演示</title> <link href="https://cdn.bootcss.com/twitter-bootstrap/4.3.1/css/bootstrap.min.css" rel="stylesheet"> <script type="text/javascript" src="/eel.js"></script> </head> <body> <div class="container"> <div class="card mt-4"> <div class="card-body"> <h4>js & py互調測試</h4> <input type="text" class="form-control" id="in"> <p id="out"></p> <button class="btn btn-lg btn-success" onclick="doThis()">調用Python函數</button> </div> </div> </div> <script src="https://cdn.bootcss.com/jquery/3.4.1/jquery.min.js"></script> <script src="https://cdn.bootcss.com/twitter-bootstrap/4.3.1/js/bootstrap.min.js"></script> <script> // 調用python中的函數,注意需要在定義前加上async聲明異步 async function doThis(){ var par=$("#in").val(); let content = await eel.py_fun(par)(); //這里用let不用var,調用的python函數后面是兩對括號 $("#out").text(content); } // 將js中的函數暴露給python,這個貌似不怎么需要用 eel.expose(js_fun); function js_fun(a){ return('這是調用js中函數返回的結果:' + a); } </script> </body> </html>
能用HTML做界面的話,顏值肯定有保證了,接下來就是繼續研究python源代碼轉EXE或者加密打包的問題了,還有~不知道如果配上vue.js的話會不會飛起來?
以上來自:https://blog.csdn.net/lpwmm/article/details/102965286
提升一下,直接用vue+vant的前端做python前端:
py部分
import eel import time # 定義html文件所在文件夾名稱 eel.init('web') @eel.expose # 使用裝飾器,類似flask里面對路由的定義 def py_fun(a): time.sleep(2) return [t*2 for t in a] eel.start('test.html', port=0, size=(800,400))
test.html
<!DOCTYPE html> <html lang="zh-CN"> <head> <title>Eel演示</title> <meta charset="UTF-8"> <meta name="viewport" content="width=device-width, initial-scale=1.0, maximum-scale=1.0, minimum-scale=1.0, user-scalable=no"> <script src="/eel.js"></script> <script src="css/vue.js"></script> <script src="css/vant.min.js"></script> <link rel="stylesheet" href="css/vant.css"> <link rel="stylesheet" href="css/hwj.css"> </head> <body> <div id="vuebox"> <!--內容開始--> <p v-for="item in test">{{item}}</p> <van-button type="primary" @click="doThis">主要按鈕</van-button> <!--內容結束--> </div><!--vuebox--> <script> const app=new Vue({///////////////////////////start vue el:'#vuebox', data(){return{ test:[1,2,3,4] }}, methods:{ loading(){this.$toast({type: 'loading', message: '正在加載', forbidClick: true, duration: 0});}, loaded(){this.$toast.clear();this.$toast({type: 'success', message: '加載成功', forbidClick: true, duration: 500});}, async doThis(){ this.loading(); this.test = await eel.py_fun(this.test)(); this.loaded(); } }, mounted:function(){ var d = new Date(); console.log(d) }, });///////////////////////////////////end vue </script> </body> </html>
以上用到的js,css來自vant2的頁面:
<link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/vant@2.12/lib/index.css" /> <!-- 引入 Vue 和 Vant 的 JS 文件 --> <script src="https://cdn.jsdelivr.net/npm/vue@2.6/dist/vue.min.js"></script> <script src="https://cdn.jsdelivr.net/npm/vant@2.12/lib/vant.min.js"></script>
運行完,打包:
python -m eel t1.py web --onefile --noconsole --noconfirm
python -m eel 程序包.py web --noconsole --noconfirm
pyinstaller -F --noconsole -i i.ico 運行.py
完美
eel的說明文檔: