Electron笔记

搭建环境

1、安装node.js

2、npm install electron -g

3、验证:electron -v

升级:npm update electron -g

卸载:npm uninstall electron

第一个electron程序

至少需要三个文件

​ 1、package.json:用于配置electron工程(可以通过npm init 创建)

package.json {
    'name':'first',
    'version':'1.0.0.0',
    'main':'index.js'
}

​ 2、index.js:相当于electron的入口点

const { app,BrowserWindow}=require('electron')

function createWindow(){
    win=new BrowserWindow({width:800,height:600});
    win.loadFile('index.html');
    win.on('closed',()=>{
        Win=null;
    })
}
app.on(‘ready’,createWindow);

​ 3、Index.html:主窗口的UI页面文件

​ 4、启动 electron [appName]

窗口

窗口尺寸位置

BrowserWindow类创建创建时可以指定

width,height,minWidth,minHeight,maxWidth,maxHeight,x,y(x,y是起始位置)

全屏窗口

BrowserWindow类创建创建时指定{fullscreen:true}即可

BrowserWindow的setFullScreen方法可以动态将窗口设置为全屏(但fullscreenable属性必须是true)

BrowserWindow的isFullScreen()方法可以获取窗口是否为全屏

无边框、透明窗口

BrowserWindow类创建创建时指定{frame:false,transparent:true} 。frame:false表示无边框,transparent:true表示透明

窗口锁定(屏蔽操作系统的部分功能)

BrowserWindow类创建创建时指定{fullscreen:true,kiosk:true}(配合全屏使用)

页面中动态设置:

const remote=require('electron').remote;
function onClick(){
    const win=remote.getCurrentWindow();
    If(win.isKiosk()){
    	win.setKiosk(false);
    }else{
    	win.setKiosk(true);
    }
}

设置窗口图标

BrowserWindow类创建创建时指定{icon:’images/tb.ico’}属性。

还可以通过BrowserWindow的setIcon(‘path’)方法

Mac系统下不能设置图标(process.platform==’darwin’) 表示mac

优雅的加载窗口

BrowserWindow类创建时指定{show:false},窗口不会立即显示,当html完全加载后再将窗口显示出来。

win.on('ready-to-show',()=>{
	win.show()
})

父子窗口

BrowserWindow类创建创建时指定{parent:parentWin}属性,parentWin是父窗口实例(BrowserWindow)

子窗口永远在父窗口上面,父窗口关闭子窗口也关闭

模态窗口

模态窗口是子窗口,BrowserWindow类创建创建时指定{parent:parentWin,modal:true}属性

窗口之间的传值

使用ipc(interProcess Communication,进程间的通信)方式在窗口之间传递数据。ipcMain和ipcRenderer,ipcMain用于主窗口中;ipcRenderer用于其他窗口

主窗口:window1,其他窗口:window2

​ window1 -> window2

​ 在window2中通过ipcRenderer的监听事件接收window1传过来的数据

​ 在window2关闭时,会通过ipcRenderer给window1发送一个消息,window1通过ipcMain监听的事件获取 window2发来的消息

ipcMain/ipcRenderer例子

对话框

showOpenDialog

OS标准对话框:dialog.showOpenDialog([browserWindow,]options[,calback])

browserWindow允许该对话框附加到父窗口,作为父窗口的模态对话框

callback回调函数,返回选中文件或路径,如果不指定则通过showOpenDialog返回

Options:

​ title {string} 窗口标题(windows)

​ defaultPah {string} 默认路径

​ buttonLable {string} open按钮的文本

​ filter {array} 过滤文件类型

​ properties {array} 包含对话框的功能,如打开文件,目录,多选等

​ message {string} 窗口标题(mac)

打开简单的文件

const remote=require('electron').remote
const dialog=remote.dialog
function onClick_OpenFile(){
    const label=documet.getElementById('label')
    var options={};
    options.title='打开文件';
    options.message='打开文件';
    options.buttonLabel='选择';
    options.defaultPath='/drivers';
    options.properties=['openFile','multiSelections'];//文件多选:’multiSelections’
    options.filters=[
        {name:'图像文件',extensions:['jpg','bmp','png','gif']},
        {name:'视频文件',extensions:['mkv','avi','mp4']},
        {name:'所有文件(*.*)',extensions:['*']}
    ];
    label.innerText=dialog.showOpenDialog(options)
}

选择目录(创建目录mac,‘createDirectory’ )

const remote=require('electron').remote
const dialog=remote.dialog
function onClick_OpenDir(){
const label=documet.getElementById('label')
    var options={};
    options.title='选择目录';
    options.message='选择目录';
    options.buttonLabel='选择';
    options.properties=['openDirectory','createDirectory'];//’createDirectory’ mac
    label.innerText=dialog.showOpenDialog(options)
}

通过回调函数返回结果

const remote=require('electron').remote
const dialog=remote.dialog
function onClick_OpenDir(){
    const label=documet.getElementById('label')
    var options={};
    options.title='打开文件';
    options.message='打开文件';
    options.buttonLabel='选择';
    options.defaultPath='/drivers';
    options.properties=['openFile','multiSelections'];//文件多选:’multiSelections’
    options.filters=[
        {name:'图像文件',extensions:['jpg','bmp','png','gif']},
        {name:'视频文件',extensions:['mkv','avi','mp4']},
        {name:'所有文件(*.*)',extensions:['*']}
    ];
    dialog.showOpenDialog(options,(filePaths)=>{
        for(var i=0;i<filePaths.length;i++){
        label.innerText+=filePaths[i]+'\r\n'
        }
    })
}

保存对话框

showSaveDialog

OS标准对话框:dialog.showSaveDialog([browserWindow,]options[,calback])

browserWindow允许该对话框附加到父窗口,作为父窗口的模态对话框

callback回调函数,返回选中文件或路径,如果不指定则通过showOpenDialog返回

options:

​ title {string} 窗口标题(windows)

​ defaultPah {string} 默认路径

​ buttonLable {string} open按钮的文本

​ filter {array} 过滤文件类型

​ nameFieldLabel:选择文件按钮的名称

const remote=require('electron').remote
const dialog=remote.dialog
function onClick_SaveFile(){
    const label=documet.getElementById('label')
    var options={};
    options.title='保存文件';
    options.message='打开文件';
    options.buttonLabel='保存';
    options.defaultPath='/drivers';
    options.nameFieldLabel='输入名称'
    options.filters=[
        {name:'图像文件',extensions:['jpg','bmp','png','gif']},
        {name:'视频文件',extensions:['mkv','avi','mp4']},
        {name:'所有文件(*.*)',extensions:['*']}
    ];
    // label.innerText=dialog.showSaveDialog(options)
    dialog.showSaveDialog(options,(fileName)=>{
    label.innerText=fileName+'\r\n';
    })
}

消息框

showMessageBox

OS标准对话框:dialog.showMessageBox([browserWindow,]options[,calback])

browserWindow允许该对话框附加到父窗口,作为父窗口的模态对话框

callback回调函数,返回选中文件或路径,如果不指定则通过showOpenDialog返回

options:

​ title:标题

​ message:内容

​ icon:图标 (使用png图片,一般不考虑尺寸)

​ type:对话框类型

​ none,info,error,question,warning

​ buttons:自定义按钮(数组形式)

const remote=require('electron').remote
const dialog=remote.dialog
function onClick_MessageBox(){
    const label=document.getElementByID('label');
    var option={
        title:'信息',
        message:'这是一个消息提示框',
        icon:'../../kt.png',
        type:'error',
        buttons:['按钮1','按钮2','按钮3']
    };
    //label.innerText=dialog.showMessageBox(options)
    dialog.showMessageBox(options,(res)=>{
    	label.innerText='单击了第'+(res+1)+'个按钮'
    });
}

错误对话框

showErrorBox(title,context)

const remote=require('electron').remote;
const dialog=remote.dialog;
function onClick_ErrorBox(){
	dialog.showErrorBox('错误','这是一个错误')
}

window.open 创建子窗口

函数原型:window.open(url,[,title],[,attributes])

​ url:要打开的页面链接(可以是本地,也可以是web)

​ title:窗口标题,如果页面中已设置title,这个参数会被忽略

​ attributes:设置窗口的一些属性,例如窗口大小

返回值

​ BrowserWindowProxy:可以认为是BrowerWindow的代理类

​ 控制窗口

​ 获取窗口焦点 focus

​ 让窗口失去焦点 blur

​ 关闭窗口 close

​ 打印窗口 print

function onClick_OpenWindow(){
    //win=window.open('./child.html','子窗口','width=200.height=200')
    win=window.open('https://www.baidu.com')
}

function onClick_Focus(){
    if(win!=undefined){
    	win.focus()
    }
}

function onClick_Blur(){
    if(win!=undefined){
    	win.blur()
    }
}

postMessage方法传递数据

win.postMessage(data,'*')
// 父窗口发送数据
function onClick_SendMessage(){
    if(win!=undefined){
    //data是元素ID 
    	win.postMessage({'name':data.value},'*')
    }
}

//子窗口接收数据
function onLoad(){
    windows.addEventListener('message',function(e){
        //data是元素ID 
        data.innerText=e.data.name;
        alert(e.origin)//页面来源
    });
}

子窗口返回数据

通过ipcMain,ipcRenderer实现

const ipcMain = require('electron').ipcMain;
const ipcRenderer = require('electron').ipcRenderer;

// 子窗口
function winClose(){
    const win=remote.getCurrentWindow();
    //发送close关闭事件
    ipcRenderer.send('close','子窗口关闭');
    win.close()
}

// 父窗口
//监听close事件
ipcMain.on('close',(event,str)=>{
	alert(str)
});

eval 向子窗口传递方法

eval 方法用来执行javascript代码

//onClick_Eval() 父窗口调用
function onClick_Eval(){
    if(win!=undefined){
    	//eval 中的代码在子窗口中执行
    	win.eval('data.innerText="'+data.value+'"')
    }
}

Webview

<body>
    <webview id=’webview1’ src=’./index.html’ 
    Style=’width:600px;height:400px’></webview>
</body>

webview事件

function onload(){
    const webview=document.getElementById(‘webview1’);
    const loadstart=()=>{
    	console.log('loadstart');
    }

    const loadstop=()=>{
    	console.log('loadstop');
    }

    //开始加载事件
    webview.addEventListener('did-start-loading',loadstart);
    //加载完成事件
    webview.addEventListener.('did-stop-loading',loadstop);
}

在webview中装载页面中执行node.js API

webview加载的页面默认是不执行nodejs API

添加nodeintegration属性

<webview id='webview1' src='www.baidu.com'
         Style='width:600px;height:400px' nodeintegration>
</webview>

webview常用API

function onClick_API(){
    webview=document.getElementById('webview1')
    //加载指定的页面
    webview.loadURL('https://www.baidu.com');
    //页面重新加载
    webview.reload();
    //获取标题
    console.log(webview.getTitle())
    //获取URL地址
    console.log(webview.getURL())
    //执行webview页面中的函数 func1
    webview.executeJavaScript('func1()'')
}

获取屏幕尺寸和鼠标绝对值

const electron = require('electron');

const remote=electron.remote;
function onClick_Screen(){
    const win=remote.getCurrentWindow();
    //PC 屏幕大小
    const {width,height} = electron.screen.getPrimaryDisplay().workAreaSize;
    //设置窗口大小 true表示开启动画效果
    win.setSize(width,height,true);
    win.setPosition(0,0)
    //获取鼠标的绝对位置
    console.log('x:'+election.screen.getCursorScreenPoint().x);
    console.log('y:'+election.screen.getCursorScreenPoint().y);
}

Windows平台添加进度条

const electron = require('electron');
const remote=electron.remote;

function onClick_ProgressBar(){
    const win=remote.getCurrentWindow();
    win.setProgressBar(0.3)
}

原生应用菜单

模板创建菜单

const {app,BrowserWindow,Menu}=require('electron');

function createWindow(){
	win=new BrowserWindow({width:800,height:600});
	win.loadFile('index.html');
	//定义菜单模板
    const template=[{
        label:'文件',
        submenu:[ { //子菜单 
            label:'关于',
            role:'about' //角色 弹出模态框 角色自带逻辑动作
            click:()=>{
            	var aboutWin=new BrowserWindow({width:300,height:200, parent:win,modal:true})
        	}
        },{
            type:'separator' //分割线
        },{
            label:'关闭',
            accelerator:'Command+Q',//快捷键
            click:()=>{
                win.close();
            }
        }
    ]},
	{label:'编辑',submenu:[]}];

    if(process.platform=='darwin'){
        //添加Mac特有的菜单项
    }
    const menu=Menu.buildFromTemplate(template);
    Menu.setApplicationMenu(menu);
    win.on('closed',()=>{
        console.log('closed');
        win=null;
    })
}

菜单详情

菜单类型:

通过type指定 {type:‘checkbox’,label:‘checkBtn’}

​ 1、normal:默认菜单

​ 2、separator:分割线 (type)

​ 3、submenu:子菜单

​ 4、checkbox:多选菜单 (type)

​ 5、radio:单选菜单 (type)

菜单图标:

通过icon属性指定,图标会按原尺寸显示,一般图标大小为16x16

{
	label:'文件'
    submenu:[ {
    	label:'打开',
    	icon:'../../openFolder.png' //图片路径
    } ]
}

动态创建图标:

const electron=require('electron');
const remote=electron.remote;
const Menu=remote.Menu;
const MenuItem=remote.MenuItem;

var coustomMenu=new Menu();//动态添加的菜单
function originMenu(){
    const menu=new Menu();
    var icon=''
    if(process.platform=='win32'){
    	icon='../../folder.ico';
    }else{
    	icon='../../folder.png'
    }
    var menuItemOpen=new MenuItem({label:'open',icon:icon});
    var menuItemSave=new MenuItem({label:'save',click=>{/*... 处理函数 ...*/}});
    var menuItemFile=new MenuItem({label:'文件',
    submenu:[menuItemOpen,menuItemSave]});
    var menuItemCustom=new MenuItem({label:'定制菜单', submenu:coustomMenu})
    const menu=new Menu();
    menu.append(menuItemFile);
    menu.append(menuItemCoustom);
    Menu.setApplicationMenu(menu);
}

function AddMenu(){
    var type='normal';
    if(radio.checked){
    	type='radio'
    }
    if(checkbox.checked){
    	type='checkbox'
    }
    customMenu.append(new MenuItem({label:menuitem.value,type:type}))//添加菜单
    menuitem.value=''
    radio.checked=false;
    checkbox.checked=false;
    Menu.setApplicationMenu(Menu.getApplicationMenu())//让菜单生效
}

上行文菜单

const electron=require('electron');
const remote=electron.remote;
const Menu=remote.Menu;
const MenuItem=remote.MenuItem;
const dialog=remote.dialog;
  
function winLoad(){
    const menu=new Menu();
    const win=remote.getCurrentWindow();
    var menuItemOpen=new MenuItem({
            label:'打开',click:()=>{
            var paths=dialog.showOpenDialog({properties:['openFile']});
            if(paths!=undefined){
                win.setTitle(paths[0])
            }
        }
    })
    var menuItemSave=new MenuItem({label:'保存'});
    menu.append(menuItemOpen);
    menu.append(menuItemSave);
    
    panel.addEventListener('contextmenu',function(event){
        event.preventDefault();
        menu.popup({x:event.x,y:event.y});
        return false;
    });

}

应用程序托盘

const { app, Menu, Tray, BrowserWindow } = require('electron')
const path = require('path');
let win;
let tray;
let contextMenu;

function createWindows() {
  win = new BrowserWindow({ width: 800, height: 600 });
  win.loadFile('index.html');
  //创建托盘
  var trayIcon = path.join(__dirname, 'images');
  tray = new Tray(path.join(trayIcon, 'orderline.png'));
  tray.setToolTip('This is my application.');
  //系统托盘右键菜单
  var trayMenuTemplate = [{
      label: '设置',
      click: function () { } 
    }, {
      label: '帮助',
      click: function () { }
    }, {
      label: '关于',
      click: function () { }
    }, {
      label: '退出',
      click: function () {
        app.quit();
      }
    }
  ];

  contextMenu = Menu.buildFromTemplate(trayMenuTemplate);
  tray.setContextMenu(contextMenu);
  // win.webContents.openDevTools()
  win.on('closed', () => {
    win = null
  });
}

app.on('ready', createWindows)

app.on('windows-all-closed', () => {
  if (process.platform !== 'darwin') {
    app.quit();
  }
});

app.on('activate', () => {
  if (win === null) {
    createWindows();
  }
});

动态设置托盘图标

if(tray!=undefiend){
	tray.setImage('../../node.png');
}

动态设置托盘标题(only mac)

if(tray!=undefiend){
	tray.setTitle('hello electron');
}

动态设置托盘提示信息

if(tray!=undefiend){
	tray.setToolTip('hello electron');
}

动态删除托盘

if(tray!=undefiend){
    tray.destroy();
    tray=undefined;
}

Windows托盘添加气泡信息

if(tray!=undefiend){
    tray.displayBalloon({
        title:'有消息了',
        icon:'../../msg.png',
        content:'消息内容'
    });
}

// ----------------------------------------------------
//气泡显示事件
tray.on('ballon-show',()=>{
	// ……
})

//气泡单击事件
tray.on('ballon-click',()=>{
	// ……
})

//气泡关闭事件
tray.on('ballon-closed',()=>{
	// ……
})

拖拽操作

//禁用鼠标经过事件
panel.ondragover=()=>{return false;}
//放下事件
panel.ondrop=(e)=>{
    e.preventDefault();//屏蔽默认操作
    for(let f of e.dataTransfer.files){
        image.src=f.path;
        break;
    }
}

摄像头操作

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <meta http-equiv="X-UA-Compatible" content="ie=edge">
    <title>摄像头操作</title>
</head>
<body>
    <video autoplay style="width: 300px; height:300px"></video>    
</body>
<script>
    function initialize(){
        video=document.querySelector('video')
        let errorCallBack=(error)=>{
            console.log(`连接视频流失败:${error.message}`);
        }
        window.navigator.webkitGetUserMedia({video:true},(localStream)=>{
            video.src=window.URL.createObjectURL(localStream)
        },errorCallBack)
    }
    window.onload=initialize();
</script>
</html>

Electron-packager使用

安装:npm install electron-packager -g

基本打包命令:

​ 进入到工程目录

# 方式1
electron-packager . --platform=win32 --arch=x64 --icon trainmpa.ico --out=./out --asar --electron-version=4.2.12 --executable-name trainMap

# 方式2
electron-packager . --electron-version=4.2.12 --executable-name appName

资源文件处理:

​ 1、复制资源文件到打包后的目录中

​ 2、开发时资源放到工程目录下,直接打包

​ 3、尽可能使用web资源

修改应用程序名称:

​ 1、修改工程中的package.json,再打包

​ 2、打包时指定程序名称:

electron-packager . appName --electron-version=4.2.12

修改应用程序图标:

添加icon属性:

​ --icon=’图标路径’

​ Windows图标是ico

​ Mac图标icns

生成asar文件(打包工程源码)

添加asar参数

electron-packager . appName --asar --electron-version=4.2.12

提取asar

asar extract app.asar xyz(将app.asar文件内容提取到xyz文件夹内)

元信息潜入到exe(windows)

使用win32metadata参数

​ --win32metadata.CompanyName:公司名称

​ --win32metadata.ProductName:产品名称

​ --win32metadata.FileDescription:文件描述

​ --win32metadata.OriginalFilename:原始文件名

electron-packager-interactive 工具

根据提示一步一步打包工具

  • 2
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值