Skip to content

python 3.8.10

如果使用pyhon,那么框架可分为3个部分。

  • 前端UI
  • electron主进程
  • python业务进程

概念

前端UI

负责软件界面展示和效果,你可以使用任意前端技术,请参见文档:前端模块

electron

涉及操作系统功能的业务,例如 调用操作系统api、打开文件夹、系统弹窗、等等;请参见文档:基础功能 部分

python

利用python来编写业务。

目录结构

bash
project
├── ...
├── python 业务目录
    ├── dist 使用 cx_Freeze 构建的可执行程序
    ├── main.py 入口 demo为 flask框架
    ├── requirements.txt python依赖
    ├── setup.py 模块 cx_Freeze 的构建脚本
    ├── fastapi-demo.py

单独开发、调试 python项目

  1. 编辑./cmd/bin.js
javascript
// bin开发配置
  /**
   * 执行自定义命令
   * ee-bin exec
   */
  exec: {
    python: {
      directory: './python',
      cmd: 'python',
      args: ['./main.py', '--port=7074'],
      stdio: "inherit", // ignore
    },
  1. 编辑./package.json
javascript
  "scripts": {
    "dev-python": "ee-bin exec --cmds=python",
  }
  1. 调试
bash
npm run dev-python

在electron中如何运行python项目

通过cross模块的API来启动。

API模式

通过API创建python服务

javascript
  // 文件 electron/service/cross.js

  /**
   * create python service
   * In the default configuration, services can be started with applications. 
   * Developers can turn off the configuration and create it manually.
   */   
  async createPythonServer() {
    // method 1: Use the default Settings
    //const entity = await cross.run(serviceName);

    // method 2: Use custom configuration
    const serviceName = "python";
    const opt = {
      name: 'pyapp',
      cmd: path.join(getExtraResourcesDir(), 'py', 'pyapp'),
      directory: path.join(getExtraResourcesDir(), 'py'),
      args: ['--port=7074'],
      windowsExtname: true,
      appExit: true,
    }
    const entity = await cross.run(serviceName, opt);
    logger.info('server name:', entity.name);
    logger.info('server config:', entity.config);
    logger.info('server url:', entity.getUrl());

    return;
  }

跟随软件启动

如果你希望桌面软件运行时就启动python可执行程序,有以下方式。

预加载模块,直接引入并调用。

javascript
// 文件 electron/preload/index.js

/*************************************************
 ** preload为预加载模块,该文件将会在程序启动时加载 **
 *************************************************/
const { crossService } = require('../service/cross');

function preload() {
  // 直接调用
  crossService.createPythonServer();
}

/**
* 预加载模块入口
*/
module.exports = {
  preload
}

获取服务地址

根据程序name,获取本地服务地址,一般为 ip:port (http://127.0.0.1:7074)。如果配置中的端口7074被占用,则框架会随机生成一个。

javascript
  /**
   * Get service url
   */  
  async getUrl(args) {
    const { name } = args;
    const serverUrl = cross.getUrl(name);
    return serverUrl;
  }

kill进程

通过程序name,kill进程,或kill所有进程。

javascript
  /**
   * kill service
   * By default (modifiable), killing the process will exit the electron application.
   */  
  async killServer(args) {
    const { type, name } = args;
    if (type == 'all') {
      cross.killAll();
    } else {
      cross.killByName(name);
    }

    return;
  }

通信

http是当前最通用的通信协议,后续可能为不同语言实现ipc通信。

javascript
  /**
   * Access the api for the cross service
   */
  async requestApi(name, urlPath, params) {
    const serverUrl = cross.getUrl(name);
    const apiHello = serverUrl + urlPath;
    console.log('Server Url:', serverUrl);

    const response = await axios({
      method: 'get',
      url: apiHello,
      timeout: 1000,
      params,
      proxy: false,
    });
    if (response.status == 200) {
      const { data } = response;
      return data;
    }

    return null;
  }