连接Python 3和Electron/Node.JS:构建现代桌面应用程序

  • Post author:
  • Post category:python



目录


先决条件


第1步——设置开发环境


安装Node.js和NPM


设置Python虚拟环境


创建虚拟环境


第4步——创建Node.js应用程序


如何在Electron和Python之间进行通讯


什么是IPC?


使用child_process生成Python进程


使用python-shell


使用客户端-服务器通信


概括



先决条件


本教程专为希望使用现代


Web


技术、


HTML





CSS





JS


及相关框架构建桌面应用程序和


GUI





Python


开发人员而设计。


为了能够轻松地学习本教程,您需要具备一些先决条件:


  • 必须具备


    Python


    知识。

  • 您应该习惯使用


    JavaScript





    HTML





    CSS


    等网络技术。

  • 您还应该熟悉


    npm


    中的


    Node.js


    软件包的安装和使用。





1


步——设置开发环境


在本节中,我们将建立一个运行示例的开发环境。我们需要在计算机上安装


Node.js


以及


NPM





Python 3




安装


Node.js





NPM


您可以遵循多种方法在开发机器上安装


Node.js





NPM


,例如使用:


  • 目标操作系统的官方二进制文件

  • 您系统的官方软件包管理器


  • NVM



    (节点版本管理器),用于在同一台计算机上安装和管理


    Node.js


    的多个版本


让我们保持简单,只需访问



官方网站



并下载目标操作系统的二进制文件,然后按照说明在系统上安装


Node.js





NPM




设置


Python


虚拟环境


您很有可能已经在开发计算机上安装了


Python 3


。如果未安装,最简单的方法是访问




官方网站




并获取目标系统的二进制文件。


您可以通过打开命令行界面并运行以下命令来确保在系统上安装了


Python 3



$ python --version
Python 3.7.0


现在,让我们建立一个虚拟环境。


创建虚拟环境


在本节中,您将用


venv


创建隔离的虚拟环境以运行示例并安装所需的软件包。


虚拟环境允许您创建一个环境来隔离当前项目的依赖关系。这将使您避免具有不同版本的相同软件包之间的冲突。





Python 3


中,您可以利用


venv


模块创建虚拟环境。


现在,转到您的终端并运行以下命令来创建虚拟环境:

$ python -m venv env


接下来,您需要使用以下命令激活环境:

$ source env/bin/activate





Windows


上,您可以使用



Scripts\activate.bat



文件激活虚拟环境,如下所示:

$ env\Scripts\activate.bat


就是这样。现在,您已经激活了虚拟环境,并且可以为示例安装软件包。





4


步——创建


Node.js


应用程序


现在,我们已经通过将


Node.js





npm


一起安装并创建


Python


虚拟环境,来设置了用于


Python





Electron


开发的开发环境,让我们继续创建


Electron


应用程序。


首先,为项目创建一个文件夹,并使用以下命令在其中创建



package.json



文件:

$ mkdir python-nodejs-example
$ cd python-nodejs-example
$ npm init -y


Npm





init


命令会产生一个具有以下默认值






package.json




文件




{
  "name": "python-nodejs-example",
  "version": "1.0.0",
  "description": "",
  "main": "index.js",
  "scripts": {
    "test": "echo \"Error: no test specified\" && exit 1"
  },
  "keywords": [],
  "author": "",
  "license": "ISC"
}


您可以自定义这个文件中您认为适合您的项目的值,您也可以简单地使用这个简单示例的默认值。


接下来,我们需要在项目的文件夹中创建两个文件



index.html







index.js




$ touch index.js 
$ touch index.html


如何在


Electron





Python


之间进行通讯


在本节中,我们将看到可用于实现


Electron





Python


进程之间的通信的各种可用方法。


什么是


IPC





根据



维基百科





在计算机科学中,进程间通信(


IPC


)特指操作系统提供的机制,允许进程管理共享数据。通常,应用程序可以使用


IPC


,分类为客户机和服务器,其中客户机请求数据,服务器响应客户机请求。


IPC


是指操作系统支持的一组机制,以使不同的本地或远程进程能够相互通信。例如,在我们的例子中,我们希望允许在


Electron


进程和


Python


进程之间进行通信。


让我们看一些实现


IPC


的方法。


使用


child_process


生成


Python


进程


Node.js


提供了


{


child_process


]






https://nodejs.org/api/child_process.html



)模块,该模块允许您生成子进程。


让我们用它来生成一个


Python


进程并运行一个简单的



calc.py



脚本。


我们将使用



simplecalculator






Python


中进行简单的计算,因此我们首先运行以下命令进行安装:

$ sudo pip install simplecalculator


首先,在项目的文件夹中,创建一个



py



文件夹,并在其中创建一个



calc.py



文件:

$ mkdir py & cd py
$ touch calc.py


打开



calc.py



文件,并添加以下


Python


代码,该代码执行计算并将结果打印到标准输出中:

from sys import argv
from calculator.simple import SimpleCalculator

def calc(text):
	"""based on the input text, return the operation result"""
	try:
		c = SimpleCalculator()
		c.run(text)
		return c.log[-1]
	except Exception as e:
		print(e)
		return 0.0

if __name__ == '__main__':
    print(calc(argv[1]))


接下来,创建一个



renderer.js



文件,并添加以下代码以生成


Python


进程并执行



py/calc.py



脚本:

function sendToPython() {
  var python = require('child_process').spawn('python', ['./py/calc.py', input.value]);
  python.stdout.on('data', function (data) {
    console.log("Python response: ", data.toString('utf8'));
    result.textContent = data.toString('utf8');
  });

  python.stderr.on('data', (data) => {
    console.error(`stderr: ${data}`);
  });

  python.on('close', (code) => {
    console.log(`child process exited with code ${code}`);
  });
}

btn.addEventListener('click', () => {
  sendToPython();
});

btn.dispatchEvent(new Event('click'));


接下来,打开



index.html



文件并按如下所示进行更新:

<!DOCTYPE html>
<html>
<head>
    <meta charset="UTF-8">
    <title>Calling Python from Electron!</title>
</head>

<body>
    <h1>Simple Python Calculator!</h1>
    <p>Input something like <code>1 + 1</code>.</p>
    <input id="input" value="1 + 1"></input>
    <input id="btn" type="button" value="Send to Python!"></input>
    </br>
    Got <span id="result"></span>
    
    <script src="./renderer.js"></script>

</body>
</html>


使用


python-shell


在了解了如何使用


child_process





Electron





Python


之间进行通信之后,现在让我们看看如何使用


python-shell





python-shell



是一个


npm


软件包,它提供了一种从


Node.js


运行


Python


脚本的简便方法,并具有基本且有效的进程间通信和错误处理。


您可以将


python-shell


用于:


  • 生成


    Python


    脚本

  • 在文本、


    JSON


    和二进制模式之间切换

  • 通过


    stdin





    stdout


    流进行数据传输

  • 在发生错误的情况下获取堆栈跟踪


转到终端,然后运行以下命令从


npm


安装


python-shell



$ npm install --save python-shell


在撰写本文时,


python-shell v1.0.8


已安装在我们的项目中。


接下来,打开



renderer.js



文件并按如下所示更新


sendToPython()


函数:

function sendToPython() {
  var { PythonShell } = require('python-shell');

  let options = {
    mode: 'text',
    args: [input.value]
  };

  PythonShell.run('./py/calc.py', options, function (err, results) {
    if (err) throw err;
    // results is an array consisting of messages collected during execution
    console.log('results: ', results);
    result.textContent = results[0];
  });
}


使用客户端





服务器通信


现在让我们看看使用


HTTP


服务器在


Python





Electron


之间实现通信的另一种方法。


回到终端并运行以下命令来安装


Flask





Flask-Cors



$ pip install flask
$ pip install Flask-Cors


接下来,在您项目的



py



文件夹中,创建一个



server.py



文件,并添加以下代码以运行


Flask


服务器,该服务器仅执行计算并将结果作为


HTTP


响应返回:

import sys
from flask import Flask
from flask_cors import cross_origin
from calculator.simple import SimpleCalculator

def calcOp(text):
	"""based on the input text, return the operation result"""
	try:
		c = SimpleCalculator()
		c.run(text)
		return c.log[-1]
	except Exception as e:
		print(e)
		return 0.0

app = Flask(__name__)

@app.route("/<input>")
@cross_origin()
def calc(input):    
    return calcOp(input)

if __name__ == "__main__":
    app.run(host='127.0.0.1', port=5001)


接下来,打开



renderer.js



文件,并添加以下代码以生成


Python


并运行



server.py



文件:

let input = document.querySelector('#input')
let result = document.querySelector('#result')
let btn = document.querySelector('#btn')

function sendToPython() {
  var { PythonShell } = require('python-shell');

  let options = {
    mode: 'text'
  };
  
  PythonShell.run('./py/server.py', options, function (err, results) {
    if (err) throw err;
    // results is an array consisting of messages collected during execution
    console.log('response: ', results);
  });
}

function onclick(){

  fetch(`http://127.0.0.1:5001/${input.value}`).then((data)=>{      
      return data.text();
      
  }).then((text)=>{
    console.log("data: ", text);
    result.textContent = text;
  }).catch(e=>{
    console.log(e);
  })
}
sendToPython();

btn.addEventListener('click', () => {
  onclick();
});

btn.dispatchEvent(new Event('click'))


概括


在本教程中,我们已经为


Python


开发人员介绍了


electronic


,如果他们想使用基于


HTML





CSS





JavaScript


的现代网络技术为自己的


Python


应用程序构建


GUI


,那么这将是一个很好的工具。我们还看到了连接


Python





electronic


的不同方法,例如


child_process





python-shell





HTTP





Flask


)服务器。