【electron】监听快捷键打开新窗口

简介

Electron是一个使用 JavaScript、HTML 和 CSS 构建桌面应用程序的框架。

思路:监听键盘keyDownEvent > 功能函数funObj > 快捷键映射功能函数keyList > 当前快捷键匹配功能函数keyMap > 执行doFun

窗口通信:主传electron > electron传子,反之,子传electron > electron传主

  1. 渲染文件vue

(1)监听keydown或keyup
window.addEventListener("keydown", doKeyDownEvent, false);

const doKeyDownEvent = (e: KeyboardEvent) => {
  // 快捷键功能映射对象
  const funObj = [
    {
      name: "backToHome",
      fun: backToHome,
    },
    {
      name: "saveData",
      fun: updateWorkData,
    },
    //
  ];
  keyDownEvent(e, store, mainSceneObj, funObj);
};
const doKeyUpEvent = (e: KeyboardEvent) => {
  keyUpEvent(e, store, mainSceneObj);
};

(2)功能键-功能函数-键盘key

//功能键-功能函数名映射
const keyList = [
  {
    alias: "显示或隐藏辅助页",
    name: "assistDisplayMode",
    key: "ctrl+F5",
  },
  //...
];

export const keyMap = (event: KeyboardEvent, keyList: any) => {
  //处理一些组合键
  let auxKey: string = '';
  if (!event.shiftKey && !event.ctrlKey && event.altKey) {
    auxKey = "alt";
  } else if (!event.shiftKey && event.ctrlKey && !event.altKey) {
    auxKey = "ctrl";
  } else if (event.shiftKey && !event.ctrlKey && !event.altKey) {
    auxKey = "shift";
  } else if (!event.shiftKey && event.ctrlKey && event.altKey) {
    auxKey = "alt+ctrl";
  } else if (event.shiftKey && !event.ctrlKey && event.altKey) {
    auxKey = "alt+shift";
  } else if (event.shiftKey && event.ctrlKey && !event.altKey) {
    auxKey = "ctrl+shift";
  } else if (event.shiftKey && event.ctrlKey && event.altKey) {
    auxKey = "alt+ctrl+shift";
  } else {
    auxKey = "";
  };
  const keyValue: string = auxKey ? auxKey + '+' + event.key : event.key;
  const keyInfo: any = keyList.find((k: any) => k.key === keyValue);

  return keyInfo ? keyInfo.name : null;
}

export const keyDownEvent = (event: KeyboardEvent, store: any, mainSceneObj: any, funObj: any = null) => {
  event.preventDefault();
  const keyName = keyMap(event, keyList);

  // console.log("keydown", keyName)

  //Esc - 撤销编辑
  if (keyName == "cancel") {
    doFun(funObj, keyName);
  }
  //打开辅助页
  else if (keyName == "assistDisplayMode") {
    const arr = {}//传给childwin的数据
    // 调用electron声明方法
    window.api.send("m2e_send", { method: "createChildWindow", obj: arr });
  }
}

const doFun = (funObj: any, keyName: string, params: any = null) => {
  funObj.forEach(f => {
    if (f.name == keyName) {
      if (params) {
        f.fun(params);
      } else {
        f.fun()
      }
    }
  });
}
  1. electron文件

包含窗口定义,通信事件

(1)入口文件

//main.ts
const { app, BrowserWindow, ipcMain, dialog } = require("electron");
let mainWin;
let childWin;
const NODE_ENV = process.env.NODE_ENV;

/* 打开主窗体 */
const createMainWindow = () => {
// 	BrowserWindow初始化窗口信息
    mainWin = new BrowserWindow({
        width: 1920,
        height: 1080,
        
        webPreferences: {
            //@ts-ignore
            nodeIntegration: process.env.ELECTRON_NODE_INTEGRATION,
            contextIsolation: !process.env.ELECTRON_NODE_INTEGRATION,
            nodeIntegrationInWorker: true,
            webSecurity: false,
            preload: path.join(__dirname, "preload.ts"),
        },
        title: "主窗口",
        show: false,
    })
    mainWin.loadURL(
        NODE_ENV === 'development' ? 'http://localhost:5173/' : `file://${path.join(__dirname, '../dist/index.html')}`
    )

    if (NODE_ENV === 'development') {
        mainWin.webContents.openDevTools()//调试工具
    } 

    mainWin.once("ready-to-show", () => {
        mainWin.show();
        mainWin.maximize();
    });
}
const createChildWindow = () => {
// 	BrowserWindow初始化窗口信息,同createMainWindow
};

// electron初始化之后默认打开主窗口
app.whenReady().then(() => {
  mainWin = null;
  childWin = null;
  createMainWindow();
});

//m2e_send:主窗口给子窗口
ipcMain.on("m2e_send", mainWinToElectron);

//mainWin -> electron
function mainWinToElectron (e, res) {
    // console.log("mainWIn", res)
    if (res.method == "changeChildWinState") changeChildWinState()
}

/* 打开辅助窗体 */
function changeChildWinState (e, res) {
    if (childWin != null) {
        childWin.close();
    } else {
        createChildWindow()
    }
}

(2)渲染器

contextBridge将electron定义的事件抛出,使得渲染文件vue可以通过window.api.send("m2e_send", { method: "createChildWindow", obj: arr });调用

//preload.ts
const { contextBridge, ipcRenderer } = require("electron");

contextBridge.exposeInMainWorld("api", {
  send: (channel, data) => {
    // whitelist channels
    let validChannels = ["m2e_send"];
    if (validChannels.includes(channel)) {
      ipcRenderer.send(channel, data);
    }
  },
});
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值