久久国产成人av_抖音国产毛片_a片网站免费观看_A片无码播放手机在线观看,色五月在线观看,亚洲精品m在线观看,女人自慰的免费网址,悠悠在线观看精品视频,一级日本片免费的,亚洲精品久,国产精品成人久久久久久久

分享

Electron Python界面開(kāi)發(fā)(通過(guò)zerorpc)

 量化貓 2020-12-12

Python 開(kāi)發(fā)GUI要么太繁瑣要么太丑,,而前端技術(shù)恰巧是最適合做漂亮UI的,。所以考慮將Python和前端技術(shù)結(jié)合,,通過(guò)進(jìn)程通信和前端框架交流,,打包成一個(gè)完整的桌面APP,。教程分成兩種實(shí)現(xiàn)方式,,一個(gè)是zerorpc進(jìn)程通信一個(gè)是http通信。

這篇教程介紹zerorpc的方式,,流程如下:

start | V+--------------------+| | start| electron +-------------> +------------------+| | sub process | || (browser) | | python server || | | || (all html/css/js) | | (business logic) || | zerorpc | || (node.js runtime, | <-----------> | (zeromq server) || zeromq client) | communication | || | | |+--------------------+ +------------------+

Electron基礎(chǔ)

詳情見(jiàn)官方文檔:
https://electronjs.org/docs

如果你可以建一個(gè)網(wǎng)站,,你就可以建一個(gè)桌面應(yīng)用程序。 Electron 是一個(gè)使用 JavaScript, HTML 和 CSS 等 Web 技術(shù)創(chuàng)建原生程序的框架,,它負(fù)責(zé)比較難搞的部分,,你只需把精力放在你的應(yīng)用的核心上即可。


有很多有名的App是用Electeon開(kāi)發(fā)的,,如:Skype和GitHub以及著名編輯器Atom,,所以這個(gè)框架在水平上是被認(rèn)可的。


Electron 可以讓你使用純 JavaScript 調(diào)用豐富的原生(操作系統(tǒng)) APIs 來(lái)創(chuàng)造桌面應(yīng)用。 你可以把它看作一個(gè)專(zhuān)注于桌面應(yīng)用的 Node. js 的變體,,而不是 Web 服務(wù)器,。

這不意味著 Electron 是某個(gè)圖形用戶(hù)界面(GUI)庫(kù)的 JavaScript 版本。 相反,,Electron 使用 web 頁(yè)面作為它的 GUI,,所以你能把它看作成一個(gè)被 JavaScript 控制的,精簡(jiǎn)版的 Chromium 瀏覽器,。

安裝

為你的新Electron應(yīng)用創(chuàng)建一個(gè)新的空文件夾,。 打開(kāi)你的命令行工具,然后從該文件夾運(yùn)行npm init,。將package.json修改一下,。

{    'name': 'your-app',    'version': '0.1.0',    'main': 'main.js',    'scripts': {      'start': 'electron .'    } }

現(xiàn)在,您需要安裝electron,。 我們推薦的安裝方法是把它作為您 app 中的開(kāi)發(fā)依賴(lài)項(xiàng),,這使您可以在不同的 app 中使用不同的 Electron 版本。 在您的app所在文件夾中運(yùn)行下面的命令:

npm install --save-dev electron

使用

electron模塊包含了Electron提供的所有API和功能,,引入方法和普通Node.js模塊一樣:

const electron = require('electron')

electron 模塊所提供的功能都是通過(guò)命名空間暴露出來(lái)的,。 比如說(shuō): electron.app負(fù)責(zé)管理Electron 應(yīng)用程序的生命周期, electron.BrowserWindow類(lèi)負(fù)責(zé)創(chuàng)建窗口,。 下面是一個(gè)簡(jiǎn)單的main.js文件,,它將在應(yīng)用程序準(zhǔn)備就緒后打開(kāi)一個(gè)窗口:

const {app, BrowserWindow} = require('electron') function createWindow () { // 創(chuàng)建瀏覽器窗口 win = new BrowserWindow({width: 800, height: 600}) // 然后加載應(yīng)用的 index.html。 win.loadFile('index.html') } app.on('ready', createWindow)

您應(yīng)當(dāng)在 main.js 中創(chuàng)建窗口,,并處理程序中可能遇到的所有系統(tǒng)事件,。 下面我們將完善上述例子,添加以下功能:打開(kāi)開(kāi)發(fā)者工具,、處理窗口關(guān)閉事件,、在macOS用戶(hù)點(diǎn)擊dock上圖標(biāo)時(shí)重建窗口,添加后,,main. js 就像下面這樣:

const {app, BrowserWindow} = require('electron')  // Keep a global reference of the window object, if you don't, the window will   // be closed automatically when the JavaScript object is garbage collected.   let win  function createWindow () {    // 創(chuàng)建瀏覽器窗口,。     win = new BrowserWindow({width: 800, height: 600})    // 然后加載應(yīng)用的 index.html。     win.loadFile('index.html')    // 打開(kāi)開(kāi)發(fā)者工具     win.webContents.openDevTools()    // 當(dāng) window 被關(guān)閉,,這個(gè)事件會(huì)被觸發(fā),。     win.on('closed', () => {      // 取消引用 window 對(duì)象,如果你的應(yīng)用支持多窗口的話,,       // 通常會(huì)把多個(gè) window 對(duì)象存放在一個(gè)數(shù)組里面,,       // 與此同時(shí),你應(yīng)該刪除相應(yīng)的元素,。       win = null    })  }  // Electron 會(huì)在初始化后并準(zhǔn)備   // 創(chuàng)建瀏覽器窗口時(shí),,調(diào)用這個(gè)函數(shù),。   // 部分 API 在 ready 事件觸發(fā)后才能使用。   app.on('ready', createWindow)  // 當(dāng)全部窗口關(guān)閉時(shí)退出,。   app.on('window-all-closed', () => {    // 在 macOS 上,,除非用戶(hù)用 Cmd + Q 確定地退出,     // 否則絕大部分應(yīng)用及其菜單欄會(huì)保持激活,。     if (process.platform !== 'darwin') {      app.quit()    }  })  app.on('activate', () => {    // 在macOS上,,當(dāng)單擊dock圖標(biāo)并且沒(méi)有其他窗口打開(kāi)時(shí),     // 通常在應(yīng)用程序中重新創(chuàng)建一個(gè)窗口,。     if (win === null) {      createWindow()    }  })  // 在這個(gè)文件中,,你可以續(xù)寫(xiě)應(yīng)用剩下主進(jìn)程代碼。   // 也可以拆分成幾個(gè)文件,,然后用 require 導(dǎo)入,。 

最后,創(chuàng)建你想展示的 index.html

<!DOCTYPE html> <html> <head> <meta charset='UTF-8'> <title>Hello World!</title> </head> <body> <h1>Hello World!</h1> We are using node <script>document.write(process.versions.node)</script>, Chrome <script>document.write(process.versions.chrome)</script>, and Electron <script>document.write(process.versions.electron)</script>. </body> </html>

啟動(dòng)

在創(chuàng)建并初始化完成 main.js,、 index.htmlpackage.json之后,,您就可以在當(dāng)前工程的根目錄執(zhí)行 npm start 命令來(lái)啟動(dòng)剛剛編寫(xiě)好的Electron程序了。


Python部分

安裝pip install zerorpc,。在項(xiàng)目根目錄創(chuàng)建文件夾py,,用于存放Python相關(guān)代碼。新建一個(gè)python文件,,命名為api.py。敲入如下demo,。

import zerorpcclass HelloRPC(object):    def hello(self, name):        return 'Hello, %s' % names = zerorpc.Server(HelloRPC())s.bind('tcp://0.0.0.0:4242')s.run()

然后命令行里運(yùn)行python api.py,。再另一個(gè)終端輸入zerorpc tcp://localhost:4242 hello NXB,如果得到Hello,NXB則沒(méi)有問(wèn)題。

Electron部分

接著之前的main.js后面寫(xiě),。我們首先需要node.js能夠調(diào)用Python進(jìn)程,。

const path=require('path')let pyProc = nulllet pyPort = nullconst createPyProc = () => { let port = '4242' let script = path.join(__dirname, 'py', 'api.py') pyProc = require('child_process').spawn('python', [script, port]) if (pyProc != null) { console.log('child process success') }}const exitPyProc = () => { pyProc.kill() pyProc = null pyPort = null}app.on('ready', createPyProc)app.on('will-quit', exitPyProc)

寫(xiě)完后運(yùn)行npm start看看能不能啟動(dòng)python子程序按照之前的方式測(cè)試一下能不能通信。沒(méi)問(wèn)題的話繼續(xù),。

修改我們的主頁(yè)index.html,,構(gòu)建一個(gè)輸入框。我們希望在輸入框里輸入字符,,下方可以動(dòng)態(tài)顯示Hello,XX,。

<!-- index.html --><!DOCTYPE html><html>  <head>    <meta charset='UTF-8'>    <title>Hello XX</title>  </head>  <body>    <input id='name' ></input>    <p id='result' color='black'></p>  </body>  <script>    require('./render.js')  </script></html>

在根目錄下創(chuàng)建render.js用于監(jiān)聽(tīng)輸入框,將輸入框的內(nèi)容動(dòng)態(tài)發(fā)送給python進(jìn)程,,并接收反回來(lái)的消息,。

// renderer.js var zerorpc = require('zerorpc');var client = new zerorpc.Client();client.connect('tcp://127.0.0.1:4242');let name = document.querySelector('#name')let result = document.querySelector('#result')name.addEventListener('input', () => { client.invoke('hello', name.value, (error, res) => { if(error) { console.error(error) } else { result.textContent = res } })})name.dispatchEvent(new Event('input'))

如果沒(méi)問(wèn)題的話應(yīng)該是這樣的效果:


打包

測(cè)試沒(méi)問(wèn)題之后我們需要將應(yīng)用打包,因?yàn)閯e人電腦上不一定裝了node.js或是python,。首先要裝個(gè)打包工具pip install pyinstaller,。

package.jsonscript中加入'build-python':'pyinstaller ./py/api.py --clean --distpath ./pydist',。然后運(yùn)行npm run build-python編譯一下。編譯完了可以把根目錄下生成的build文件夾和api.spec刪了,。如果中間報(bào)錯(cuò) AttributeError: module 'enum' has no attribute 'IntFlag',,就運(yùn)行pip uninstall enum34把enum34刪了。

This is likely caused by the package
enum34. Since python 3.4 there’s a standard library
enummodule, so you should uninstall
enum34, which is no longer compatible with the enum in the standard library since
enum.IntFlag was added in python 3.6

之前子進(jìn)程是通過(guò)調(diào)用python命令運(yùn)行的,,現(xiàn)在我們要換成生成的可執(zhí)行程序,。修改main.js

// let script = path.join(__dirname, 'py', 'api.py')   // pyProc = require('child_process').spawn('python', [script, port])   let script = path.join(__dirname, 'pydist', 'api','api')  pyProc = require('child_process').execFile(script, [port])

運(yùn)行npm start可以查看效果。

在根目錄運(yùn)行npm install electron-packager --save-dev安裝Electron打包模塊,。然后將'pack-app': './node_modules/.bin/electron-packager . --overwrite --ignore=py$'寫(xiě)入package.json的script中,。

運(yùn)行npm run pack-app打包程序。最后會(huì)生成可執(zhí)行文件,,復(fù)制到別的電腦也可以運(yùn)行,。



nofacer/Python_GUI_with_Electron? github.com

    本站是提供個(gè)人知識(shí)管理的網(wǎng)絡(luò)存儲(chǔ)空間,所有內(nèi)容均由用戶(hù)發(fā)布,,不代表本站觀點(diǎn),。請(qǐng)注意甄別內(nèi)容中的聯(lián)系方式、誘導(dǎo)購(gòu)買(mǎi)等信息,,謹(jǐn)防詐騙,。如發(fā)現(xiàn)有害或侵權(quán)內(nèi)容,請(qǐng)點(diǎn)擊一鍵舉報(bào),。
    轉(zhuǎn)藏 分享 獻(xiàn)花(0

    0條評(píng)論

    發(fā)表

    請(qǐng)遵守用戶(hù) 評(píng)論公約

    類(lèi)似文章 更多