使用方法
前端
在项目根目录下新建web文件夹,lib文件夹用于存放第三方库文件
| favicon.ico | index.html | +---css | | index.css | | | \---lib | bootstrap-icons.css | bootstrap.min.css | \---js | index_jquery.js | +---lib | bootstrap.bundle.min.js | eel.js | jquery.min.js | \---util messageUtil.js
|
在Html中导入eel的JavaScript文件,属于固定写法,需要在index.js前调用
<script type="text/javascript" src="/eel.js"></script>
|
前端暴露方法
在JavaScript中调用eel.expose用于向后端暴露方法,供后端使用。后端使用需要使用两个括号
eel.expose(test) function test(a, b) { ... }
|
eel.updateFilesNum(a, b)()
|
后端暴露方法
在函数中使用@eel.expose注解,用于将后端的方法暴露给前端使用
@eel.expose def test(a, b): ...
|
let res = await eel.test(a, b)()
|
HTML选择文件夹
由于浏览器安全机制,因此直接使用input标签选择文件夹只能返回文件名称,因此可以通过Python的Tkinter库打开文件夹选择器,进而得到文件夹路径
@eel.expose def open_file_explorer(): """ 打开文件浏览器 :return: """ file_path = askopenfilename() return file_path
|
搭配Vue使用
创建vue项目,这里使用vue3创建,创建命令如下:
Python配置
新建run.py启动文件
import eel import sys import platform
@eel.expose def say_hello_py(name): """ 暴露Python的方法,供js调用 :param name: :return: """ print("Hello, " + name + " from Python!") print("调用js方法") eel.say_hello_js(name)()
def start_eel(develop): """ 启动eel :param develop: :return: """ if develop: directory = 'src' app = 'chrome' page = {'port': 9100} eel_kwargs = dict( mode=app, host="localhost", port=9000, ) else: directory = 'web' app = 'chrome' page = 'index.html' eel_kwargs = dict( mode=app, port=0, size=(1280, 800), ) eel.init(directory) try: eel.start(page, **eel_kwargs) except EnvironmentError: if sys.platform in ["win32", "win64"] and int(platform.release()) >= 10: eel.start(page, mode="edge", **eel_kwargs) else: raise
if __name__ == "__main__": print("Opening eel...") start_eel(True) start_eel(False)
|
前端配置
安装vite-plugin-html插件
npm install vite-plugin-html -D
|
由于vue3使用vite,于是修改vite.config.js文件
import {fileURLToPath, URL} from 'node:url' import {resolve} from 'path'; import {createHtmlPlugin} from 'vite-plugin-html'
import {defineConfig} from 'vite' import vue from '@vitejs/plugin-vue'
export default defineConfig({ plugins: [ vue(), createHtmlPlugin({ minify: true,
inject: { data: { title: 'index', injectScript: process.env.NODE_ENV === 'production' ? `<script src="/eel.js"></script>` : `<script src="http://localhost:9000/eel.js"></script><script>window.eel.set_host("ws://localhost:9000");</script>`, }, }, }), ], build: { outDir: resolve('./web'), emptyOutDir: true, target: 'esnext', minify: 'esbuild', }, resolve: { alias: { '@': fileURLToPath(new URL('./src', import.meta.url)) } }, server: { port: 9100, } })
|
修改index.html
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <link rel="icon" href="/favicon.ico"> <meta name="viewport" content="width=device-width, initial-scale=1.0"> <title>Vite App</title> <%- injectScript %> </head> <body> <div id="app"></div> <script type="module" src="/src/main.ts"></script> </body> </html>
|
修改main.ts
import './assets/main.css'
import {createApp} from 'vue' import App from './App.vue' import router from './router'
const app = createApp(App)
app.use(router)
declare global { interface Window { eel: any } } app.config.globalProperties.$eel = window['eel'] app.mount('#app')
|
在App.vue中使用
<script setup> import { getCurrentInstance } from 'vue' const { proxy } = getCurrentInstance()
/** * js调用python的方法 */ async function js2py() { const msg = await proxy.$eel.say_hello_py('python')() console.log(`js调用python的方法,返回的信息: ${msg}`) } </script>
|
启动
开发环境下:需要先启动vue,再启动eel
生产环境下:直接启动eel即可
打包
打包前端项目,得到web文件夹
注意:vue的路由要使用hash,createWebHashH istory
打包Python,使用pyinstaller执行命令打包主程序
pyinstaller --noconsole --add-data "web;web" --add-data "eel.sqlite;eel.sqlite" --onedir .\run.py
|
–noconsole:启动程序时不会出现命令框
–add-data:添加静态文件,比如vue打包好的前端程序;eel.sqlite数据库
–onedir:打包成文件夹
.\run.py:程序启动代码