Electron实现markdown笔记软件(五)

7 篇文章 0 订阅
7 篇文章 0 订阅

关于这个markdown笔记软件(五)——electron库

项目源码

https://github.com/andytt/ErtuilEditor

目录

关于这个markdown笔记软件(一)——总体的思路和介绍

关于这个markdown笔记软件(二)——模型层设计

关于这个markdown笔记软件(三)——视图层设计

关于这个markdown笔记软件(四)——md的渲染和生成

关于这个markdown笔记软件(五)——electron库

关于这个markdown笔记软件(六)——应用逻辑、electron对话框

关于这个markdown笔记软件(七)——其他细节、总结

package.json

node通过package.json来管理项目,其中定义了项目的依赖、程序的入口等。

{
  "name": "note",
  "version": "0.0.5",
  "description": "A small editer",
  "main": "main.js",
  "dependencies": {
    "bootstrap": "^3.3.7",
    "jquery": "^3.2.1",
    "lowdb": "^1.0.0",
    "marked": "^0.3.9",
    "node-schedule": "^1.2.5",
    "phantom": "^4.0.12"
  },
  "devDependencies": {
    "electron-packager": "^10.1.0",
    "electron": "^1.7.10",
    "electron-prebuilt": "^1.4.13",
    "electron-rebuild": "^1.6.0"
  },
  "scripts": {
    "test": "echo \"Error: no test specified\" && exit 1",
    "start": "electron main.js",
    "packager": "electron-packager . ErtuilEditer --all --out ./OutApp --version 0.0.5 --overwrite --icon=./ertuil.icns",
    "packageDarwin": "electron-packager . ErtuilEditer --platform=darwin --arch=x64 --icon=./ertuil.icns --out=./OutApp  --app-version=0.0.5  --overwrite",
    "packageLinux": "electron-packager . ErtuilEditer --platform=linux --arch=x64 --icon=./ertuil.icns --out=./OutApp  --app-version=0.0.5  --overwrite",
    "packageWindow": "electron-packager . ErtuilEditer --platform=win32 --arch=x64 --icon=./ertuil.icns --out=./OutApp  --app-version=0.0.5  --overwrite "
  },
  "author": "Ertuil",
  "license": "ISC"
}

其中main定义了程序入口,在这里就是electron的主进程main.js文件。而dependencies则是需要的依赖,在最后使用electron-packager打包的时候需要用到。

主进程

之前也说过,electron之间的进程分为主进程和渲染进程。通俗的讲,主进程负责窗口的管理,渲染进程负责GUI的渲染。他们之间通过ipcMain和ipcRender模块来进行通信。

main.js文件中主要实现了两件事情:
1. 两个窗口的管理。
2. 关于菜单栏的实现。

窗口管理

程序中主要有两个窗口,mainWindow是主要用户窗口,编辑窗口。而viewWindow这是markdown预览窗口。代码余下:

定义

const {app, BrowserWindow,Menu,shell} = require('electron')
let fs = require("fs")
const ipcMain = require('electron').ipcMain
const globalShortcut = require('electron').globalShortcut
const database = require(__dirname+'/js/database');

let mainWindow = null;
let input_window = null;//废除
let viewWindow = null;

var db_path =__dirname+"/data/data.json";

事件:

app的’window-all-closed’事件:窗口全部关闭时,如果不是Mac系统,就退出程序

app的’ready’事件:初始化数据库、加载主要窗口

app的’activate’事件:重新加载主要窗口

ipcMain的’open-view’的事件:自己定义的事件,监听到这个事件后,加载预览窗口,给出markdown预览。

加载html

在mainWindow的对象中限制了窗体的大小,并加载了index.html文件。

    mainWindow = new BrowserWindow({width: 1000, height: 800,resizable:false});
    mainWindow.loadURL('file://' + __dirname + '/index.html');
    mainWindow.on('closed', function() {
         mainWindow = null;
  });

菜单

定义菜单需要传入一个菜单模版

let template = [{
  label: '文件',
  submenu: [{
    label: '新建笔记',
    accelerator: 'CmdOrCtrl+N',
    click:function(){
      if(mainWindow){
        mainWindow.webContents.send('info_create');
      }
    }
  },{
    label: '新建标签',
    accelerator: 'CmdOrCtrl+Shift+N',
    click:function(){
      if(mainWindow){
        mainWindow.webContents.send('info_create_label');
      }
    }
  },{
    type: 'separator'
  },{
    label: '导入',
    accelerator: 'CmdOrCtrl+O',
    click:function(){
      if(mainWindow){
        mainWindow.webContents.send('info_open');
      }
    }
  },{
    label: '保存',
    accelerator: 'CmdOrCtrl+S',
    click:function(){
      if(mainWindow){
        mainWindow.webContents.send('info_save');
      }
    }
  },{
    label: '导出',
    accelerator: 'CmdOrCtrl+Shift+W',
    click:function(){
      if(mainWindow){
        mainWindow.webContents.send('info_out');
      }
    }
  },{
    type: 'separator'
  },{
    label: '删除笔记',
    accelerator: 'CmdOrCtrl+D',
    click:function(){
      if(mainWindow){
        mainWindow.webContents.send('info_remove');
      }
    }
  },{
    label: '删除标签',
    accelerator: 'CmdOrCtrl+Shift+D',
    click:function(){
      if(mainWindow){
        mainWindow.webContents.send('info_remove_label');
      }
    }
  }]
},{
  label: '编辑',
  submenu: [{
    label: '撤销',
    accelerator: 'CmdOrCtrl+Z',
    role: 'undo'
  }, {
    label: '重做',
    accelerator: 'Shift+CmdOrCtrl+Z',
    role: 'redo'
  }, {
    type: 'separator'
  }, {
    label: '插入',
    accelerator: 'CmdOrCtrl+I',
    click:function(){
      if(mainWindow){
        mainWindow.webContents.send('info_insert');
      }
    }
  }, {
    type: 'separator'
  }, {
    label: '剪切',
    accelerator: 'CmdOrCtrl+X',
    role: 'cut'
  }, {
    label: '复制',
    accelerator: 'CmdOrCtrl+C',
    role: 'copy'
  }, {
    label: '粘贴',
    accelerator: 'CmdOrCtrl+V',
    role: 'paste'
  }, {
    label: '全选',
    accelerator: 'CmdOrCtrl+A',
    role: 'selectall'
  }]
}, {
  label: '展示',
  submenu: [{
    label: '生成',
    accelerator: 'CmdOrCtrl+P',
    click:function(){
      if(mainWindow){
        mainWindow.webContents.send('info_show');
      }
    }
  },{
    type: 'separator'
  },{
    label: '切换开发者工具',
    accelerator: (function () {
      if (process.platform === 'darwin') {
        return 'Alt+Command+I'
      } else {
        return 'Ctrl+Shift+I'
      }
    })(),
    click: function (item, focusedWindow) {
      if (focusedWindow) {
        focusedWindow.toggleDevTools();
      }
    }
  }]
}, {
  label: '窗口',
  role: 'window',
  submenu: [{
    label: '最小化',
    accelerator: 'CmdOrCtrl+M',
    role: 'minimize'
  }, {
    label: '关闭',
    accelerator: 'CmdOrCtrl+W',
    role: 'close'
  }, {
    type: 'separator'
  }, {
    label: '刷新',
    accelerator: 'CmdOrCtrl+R',
    click: function (item,focusedWindow) {
      if(focusedWindow){
        focusedWindow.reload();
      }else{
        app.emit('activate');
      }
    }
  }]
}, {
  label: '帮助',
  role: 'help',
  submenu: [{
    label:'作者:Ertuil'
  },{
    label:'个人网站',
    click:function () {
      shell.openExternal('http://ertuil.top')
    }
  },{
    label:'github',
    click:function () {
      shell.openExternal('https://github.com/andytt')
    }
  },{
    label: '学习更多',
    click: function () {
      shell.openExternal('http://electron.atom.io')
    }
  }]
}]

有role属性的是系统定义的相关动作,比如复制、粘贴、关闭窗口等!

有click属性的,是自己定义的相关动作,大部分是mainWindow.webContents.send(‘xxx’);函数。这个函数的作用是向渲染进程发送事件,渲染进程监听到事件后调用相应函数、完成动作。
在渲染进程即file_manage.js文件中实现了对这些事情的监听:

ipcRenderer.on('info_create',function(){
    create_new();
});
ipcRenderer.on('info_create_label',function(){
    new_label()});
ipcRenderer.on('info_insert',function(){
    import_file()});
ipcRenderer.on('info_remove',function(){delete_note()});
ipcRenderer.on('info_remove_label',function(){delete_label()});
ipcRenderer.on('info_show',function(){save_note(false,true);});
ipcRenderer.on('info_save',function(){save_note()});
ipcRenderer.on('info_out',function(){output_file()});
ipcRenderer.on('info_open',function(){input_file()});

苹果系统下的菜单有自己的规范,因此需要在该模版之前再加一个菜单,在menucreate()函数中完成。

最后,在app的ready事件的回调函数之中,将这个模版加载,并生成了菜单:

  menucreate();
  var menu = Menu.buildFromTemplate(template);
  Menu.setApplicationMenu(menu);
  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
要在 Electron实现国际化,可以使用 Electron 提供的 i18n API。以下是实现步骤: 1. 在项目中创建一个 `locales` 文件夹,用于存放不同语言的翻译文件。 2. 在 `locales` 文件夹中创建一个 `en.json` 文件,用于存放英文翻译。 3. 在 `en.json` 文件中定义键值对,表示需要翻译的文本,如: ```json { "hello": "Hello!", "world": "World!" } ``` 4. 在 Electron 主进程中使用 `app.getPath('userData')` 获取用户数据存储路径,并在此路径下创建一个 `locales` 文件夹,用于存放用户选择的语言文件。 5. 在 Electron 渲染进程中使用 `electron.remote.app` 获取主进程实例,并使用 `app.getLocale()` 获取用户系统语言。 6. 使用 `electron.remote.require` 引入 `electron-i18n` 模块,并在 `index.html` 中使用 `data-i18n` 属性标记需要翻译的文本,如: ```html <h1 data-i18n="hello"></h1> <p data-i18n="world"></p> ``` 7. 在渲染进程中使用 `electron.remote.require('electron-i18n')` 加载翻译文件,并使用 `i18n.translator.translate()` 方法进行翻译,如: ```javascript const i18n = electron.remote.require('electron-i18n'); i18n.translator.loadLocale('en', `${app.getPath('userData')}/locales`); i18n.translator.translateDocument(document); ``` 这里使用 `loadLocale` 方法加载英文翻译文件,并使用 `translateDocument` 方法翻译整个页面。 8. 如果需要支持多语言切换,可以在渲染进程中监听 `select` 元素的 `change` 事件,并使用 `i18n.translator.setLocale()` 方法切换语言,如: ```javascript const select = document.querySelector('select'); select.addEventListener('change', () => { const locale = select.value; i18n.translator.setLocale(locale); }); ``` 这里使用 `setLocale` 方法切换语言。 以上就是在 Electron实现国际化的基本步骤。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值