使用方法

前端

在项目根目录下新建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前调用

<!--    导入eel.js,固定写法-->
<script type="text/javascript" src="/eel.js"></script>

前端暴露方法

JavaScript中调用eel.expose用于向后端暴露方法,供后端使用。后端使用需要使用两个括号

// 前端暴露
// 监听eel函数返回的文件夹名称
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标签选择文件夹只能返回文件名称,因此可以通过PythonTkinter库打开文件夹选择器,进而得到文件夹路径

@eel.expose
def open_file_explorer():
"""
打开文件浏览器
:return:
"""
file_path = askopenfilename()
return file_path

搭配Vue使用

创建vue项目,这里使用vue3创建,创建命令如下:

pnpm create vue@latest

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)() # 调用js方法


def start_eel(develop):
"""
启动eel
:param develop:
:return:
"""
if develop:
# 开发模式
directory = 'src' # 前端代码目录
app = 'chrome' # 浏览器类型
page = {'port': 9100} # vue服务的端口
eel_kwargs = dict(
mode=app,
host="localhost",
port=9000, # eel服务的端口
)
else:
# 生产模式
directory = 'web' # 前端打包后的代码目录
app = 'chrome'
page = 'index.html' # 前端入口html文件
eel_kwargs = dict(
mode=app,
port=0,
size=(1280, 800),
)
eel.init(directory)
try:
eel.start(page, **eel_kwargs)
except EnvironmentError:
# 如果没有安装chrome,则使用edge打开
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)
# 生产模式,打包的时候需要设置为False
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'

// https://vitejs.dev/config/
export default defineConfig({
plugins: [
vue(),
createHtmlPlugin({
minify: true,
/**
* 需要注入 index.html ejs 模版的数据
*/
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)

// 扩展Window接口
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即可

打包

  1. 打包前端项目,得到web文件夹

    注意:vue的路由要使用hash,createWebHashH istory

  2. 打包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:程序启动代码