首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >专栏 >(2/3)Electron知识学习 · 基础篇

(2/3)Electron知识学习 · 基础篇

作者头像
老张的哲学
发布2023-01-09 18:01:56
发布2023-01-09 18:01:56
96000
代码可运行
举报
文章被收录于专栏:NetCore 从壹开始NetCore 从壹开始
运行总次数:0
代码可运行

列举一些日常需要使用的例子

主题颜色切换

main.js

代码语言:javascript
代码运行次数:0
运行
复制
 //主题颜色切换处理
  ipcMain.handle('dark-mode:toggle', () = {
    if (nativeTheme.shouldUseDarkColors) {
      nativeTheme.themeSource = 'light'
    } else {
      nativeTheme.themeSource = 'dark'
    }
    return nativeTheme.shouldUseDarkColors
  })
  ipcMain.handle('dark-mode:system', () = {
    nativeTheme.themeSource = 'system'
  })

perload.js

代码语言:javascript
代码运行次数:0
运行
复制
//暴露主体显示
contextBridge.exposeInMainWorld('darkMode', {
  toggle: () = ipcRenderer.invoke('dark-mode:toggle'),
  system: () = ipcRenderer.invoke('dark-mode:system')
})

renderer.js

代码语言:javascript
代码运行次数:0
运行
复制
//主题颜色切换
document.getElementById('toggle-dark-mode').addEventListener('click', async () = {
    const isDarkMode = await window.darkMode.toggle()
    document.getElementById('theme-source').innerHTML = isDarkMode ? 'Dark' : 'Light'
})
document.getElementById('reset-to-system').addEventListener('click', async () = {
    await window.darkMode.system()
    document.getElementById('theme-source').innerHTML = 'System'
})

index.html

代码语言:javascript
代码运行次数:0
运行
复制
<!DOCTYPE html>
<html>
  <head>
    <meta charset="UTF-8">
    <meta http-equiv="Content-Security-Policy" content="default-src 'self'; script-src 'self'">
    <title>Hello World!</title 
    <link rel="stylesheet" type="text/css" href="./styles.css">
  </head>
  <body>
  
    <h1>Hello World!</h1>
    
    <p>Current theme source: <strong id="theme-source">System</strong></p>
    <button id="toggle-dark-mode">Toggle Dark Mode</button>
    <button id="reset-to-system">Reset to System Theme</button>
    
    <script src="./renderer.js"></script>
  </body>
</html>

style.css

代码语言:javascript
代码运行次数:0
运行
复制
@media (prefers-color-scheme: dark) {
    body { background: #333; color: white; }
  }
  
  @media (prefers-color-scheme: light) {
    body { background: #ddd; color: black; }
  }

蓝牙获取

renderer.js

代码语言:javascript
代码运行次数:0
运行
复制
async function getBuleList() {
    const device = await navigator.bluetooth.requestDevice({
        acceptAllDevices: true
    })
    document.getElementById('device-name').innerHTML =  device.name || `ID: ${device.id}`
    console.info("device",device)
}
document.getElementById('clickme').addEventListener('click',getBuleList)

main.js

代码语言:javascript
代码运行次数:0
运行
复制
//蓝牙获取
  win.webContents.on('select-bluetooth-device', (event, deviceList, callback) = {
    event.preventDefault()
    if (deviceList && deviceList.length  0) {
      callback(deviceList[0].deviceId)//必须传deviceId否则会报错
    } 
  })

index.html

代码语言:javascript
代码运行次数:0
运行
复制
    <h1>Web Bluetooth API</h1>
    <button id="clickme">Test Bluetooth</button>
    <p>Currently selected bluetooth device: <strong id="device-name"></strong></p>

注册快捷键

main.js

代码语言:javascript
代码运行次数:0
运行
复制
//注册键盘监听事件
const regEvent = () =>{
  //注册Alt+Ctl+I的监听
  globalShortcut.register('Alt+CommandOrControl+I', () = {
    console.log('Electron loves global shortcuts!')
  })
}
//窗体调用显示
app.whenReady().then(()=>{
  regEvent()
}).then(() = {
  createWindow()
})

消息通知

renderer.js

代码语言:javascript
代码运行次数:0
运行
复制
//消息通知
const NOTIFICATION_TITLE = '消息通知-子程序'
const NOTIFICATION_BODY = '我是消息'
const CLICK_MESSAGE = '你点击消息'
new Notification(NOTIFICATION_TITLE, { body: NOTIFICATION_BODY }).onclick = () = document.getElementById("output").innerText = CLICK_MESSAGE

main.js

代码语言:javascript
代码运行次数:0
运行
复制
//消息通知-主程序
function showNotification () {
  const NOTIFICATION_TITLE = '消息通知-主程序'
  const NOTIFICATION_BODY = '我是消息'
  new Notification({ title: NOTIFICATION_TITLE, body: NOTIFICATION_BODY }).show()
}

//窗体调用显示
app.whenReady().then(()=>{
  regEvent()
}).then(() = {
  createWindow()
}).then(()=>{
  showNotification()
})

进度显示

main.js

代码语言:javascript
代码运行次数:0
运行
复制
  //设置任务栏中图标的进度显示
  win.setProgressBar(0.5)//完成百分之50

系统托盘

main.js

代码语言:javascript
代码运行次数:0
运行
复制
//系统托盘
let tray = null
app.whenReady().then(() = {
  tray = new Tray('img/favicon.ico')
  let menuTrayTemplate = [
    { label: 'Item1', click:(menuItem, browserWindow, event)=>{console.info(menuItem);console.info(browserWindow);console.info(event)} },
    { label: 'Item2', click:(menuItem, browserWindow, event)=>{console.info(menuItem);console.info(browserWindow);console.info(event)} },
    { label: 'Item3', click:(menuItem, browserWindow, event)=>{console.info(menuItem);console.info(browserWindow);console.info(event)} },
    { label: 'Item4', click:(menuItem, browserWindow, event)=>{console.info(menuItem);console.info(browserWindow);console.info(event)} },
    { label: '退出' , click: () = { app.exit()}}
  ]
  const contextMenuTray = Menu.buildFromTemplate(menuTrayTemplate)
  tray.setToolTip('This is my application.')
  //设置托盘鼠标右键菜单
  tray.setContextMenu(contextMenuTray)

  // 托盘鼠标左键点击事件
  tray.on('click', () = { 
    if (win.isVisible()) {
      win.focus()
    } else {
      win.show()
    }
  })
})

顶部菜单

main.js

代码语言:javascript
代码运行次数:0
运行
复制
//顶部菜单
const menuTopTemplate = [
  {
    label: '编辑',
    submenu: [
      {
        role: 'undo'
      },
      {
        role: 'redo'
      },
      {
        type: 'separator'
      },
      {
        role: 'cut'
      },
      {
        role: 'copy'
      },
      {
        role: 'paste'
      },
      {
        role: 'pasteandmatchstyle'
      },
      {
        role: 'delete'
      },
      {
        role: 'selectall'
      }
    ]
  },
  {
    label: '查看',
    submenu: [
      {
        role: 'reload'
      },
      {
        role: 'forcereload'
      },
      {
        role: 'toggledevtools'
      },
      {
        type: 'separator'
      },
      {
        role: 'resetzoom'
      },
      {
        role: 'zoomin'
      },
      {
        role: 'zoomout'
      },
      {
        type: 'separator'
      },
      {
        role: 'togglefullscreen'
      }
    ]
  },
  {
    label: '窗体',
    role: 'window',
    submenu: [
      {
        label: '最小化',
        role: 'minimize'
      },
      {
        label: '关闭',
        role: 'close'
      }
    ]
  },
  {
    label: '帮助',
    role: 'help',
    submenu: [
      {
        label: '更多',
        click () { require('electron').shell.openExternal('http://electron.atom.io') }
      }
    ]
  },
  {
    label:'测试',
    click:(menuItem, browserWindow, event)=>{console.info(menuItem);console.info(browserWindow);console.info(event)}
  }
]
const contextMenuTop = Menu.buildFromTemplate(menuTopTemplate)
Menu.setApplicationMenu(contextMenuTop)

进程间通信

当我们主程序需要改变一些状态等操作时

这时候我们的渲染进程是不能直接操作主进程的

我们这时候就需要通过暴露主进程的接口进行操作

这里我们演示设置标题

首先我们写一个设置方法的

我们需要加载ipcMain然后注册一个事件来调用这个方法

main.js

代码语言:javascript
代码运行次数:0
运行
复制

//设置窗体标题
function handleSetTitle (event, title) {
  const webContents = event.sender
  const win = BrowserWindow.fromWebContents(webContents)
  win.setTitle(title)
}

//窗体调用显示
app.whenReady().then(()=>{
  regEvent()
}).then(() = {
  createWindow()
}).then(()=>{
  showNotification()
}).then(()=>{
  ipcMain.on('set-title', handleSetTitle)
})

preload.js

代码语言:javascript
代码运行次数:0
运行
复制
//暴露主进程信息
contextBridge.exposeInMainWorld('myAPI', {
  desktop: true,
  setTitle: (title) = ipcRenderer.send('set-title', title)
})

renderer.js

代码语言:javascript
代码运行次数:0
运行
复制
//改变标题
document.getElementById('newTitle').addEventListener('click', async () = {
    window.myAPI.setTitle("test")
})

index.js

代码语言:javascript
代码运行次数:0
运行
复制
   <h1>改变标题</h1>
    <button id="newTitle">test new newTitle</button 

创建新窗口

Electron中,与GUI相关的模块(如 dialog, menu 等)只存在于主进程,而不在渲染进程中

这里就需要用ipc模块来给主进程发送进程间消息。

使用 remote 模块, 可以调用主进程对象的方法,而无需显式地发送进程间消息 ,似于 Java 的 RMI

main.js

代码语言:javascript
代码运行次数:0
运行
复制
//创建新窗体
function handleCreateWin (event, title) {
  
  let newWin = new BrowserWindow({
    // frame: false ,//无边框设置
    width: 800,
    height: 600,
    webPreferences: {
      
    }
  })
  //加载页面
  newWin.loadFile('test.html')
  //启用开发工具。
  newWin.webContents.openDevTools();  

}

//窗体调用显示
app.whenReady().then(()=>{
  regEvent()
}).then(() = {
  createWindow()
}).then(()=>{
  showNotification()
}).then(()=>{
  ipcMain.on('set-title', handleSetTitle)
}).then(()=>{
  ipcMain.on('create-win', handleCreateWin)
})

index.html

代码语言:javascript
代码运行次数:0
运行
复制
    <h1>新建页面</h1>
    <button id="newPage">test new page</button 

renderer.js

代码语言:javascript
代码运行次数:0
运行
复制
//创建新窗口
document.getElementById('newPage').addEventListener('click', async () = {
    window.myAPI.createWin();
})

preload.js

代码语言:javascript
代码运行次数:0
运行
复制

//暴露主进程信息
contextBridge.exposeInMainWorld('myAPI', {
  desktop: true,
  setTitle: (title) = ipcRenderer.send('set-title', title),
  createWin: () = ipcRenderer.send('create-win')
})


窗体图标设置

这里我们需要把托盘图标和窗体图标设置成我们自己的图标

首先准备好素材

放在img目录下

窗体图标设置

main.js

代码语言:javascript
代码运行次数:0
运行
复制
icon: path.join(__dirname, 'img/boss.ico'), //图标设置

托盘图标设置

main.js

本文参与 腾讯云自媒体同步曝光计划,分享自微信公众号。
原始发表:2022-11-20,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 NetCore 从壹开始 微信公众号,前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体同步曝光计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • 主题颜色切换
  • 蓝牙获取
  • 注册快捷键
  • 消息通知
  • 进度显示
  • 系统托盘
  • 顶部菜单
  • 进程间通信
  • 创建新窗口
  • 窗体图标设置
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档