我希望我的Electron.js应用程序存在于系统托盘上,每当用户想要执行某些操作时,他们都可以从系统托盘执行某些操作,并将其最小化/关闭回系统托盘。我该怎么做?
我在文档中看到了tray
部分,但对实现我想要的内容没什么帮助。
这是我到目前为止在main.js
文件
var application = require('app'),
BrowserWindow = require('browser-window'),
Menu = require('menu'),
Tray = require('tray');
application.on('ready', function () {
var mainWindow = new BrowserWindow({
width: 650,
height: 450,
'min-width': 500,
'min-height': 200,
'accept-first-mouse': true,
// 'title-bar-style': 'hidden',
icon:'./icon.png'
});
mainWindow.loadUrl('file://' + __dirname + '/src/index.html');
mainWindow.on('closed', function () {
mainWindow = null;
});
mainWindow.setMenu(null);
var appIcon = null;
appIcon = new Tray('./icon-resized.png');
var contextMenu = Menu.buildFromTemplate([
{ label: 'Restore', type: 'radio' }
]);
appIcon.setToolTip('Electron.js App');
appIcon.setContextMenu(contextMenu);
});
更新
我找到了这个menubar repo,但它在linux上无法正常工作。
答案 0 :(得分:62)
我实际上很久以前就已经弄明白了,但对于那些遇到同样问题的人来说,有一种方法可以实现最小化tray
并从tray
恢复。诀窍是捕获close
和minimize
事件。
var BrowserWindow = require('browser-window'),
var mainWindow = new BrowserWindow({
width: 850,
height: 450,
title: "TEST",
icon:'./icon.png'
});
mainWindow.on('minimize',function(event){
event.preventDefault();
mainWindow.hide();
});
mainWindow.on('close', function (event) {
if(!application.isQuiting){
event.preventDefault();
mainWindow.hide();
}
return false;
});
并从Tray
var contextMenu = Menu.buildFromTemplate([
{ label: 'Show App', click: function(){
mainWindow.show();
} },
{ label: 'Quit', click: function(){
application.isQuiting = true;
application.quit();
} }
]);
答案 1 :(得分:8)
如果您希望一直显示系统托盘上的图标,直到您不退出应用程序,我就会使用方案更新代码
var { app, BrowserWindow, Tray, Menu } = require('electron')
var path = require('path')
var url = require('url')
var iconpath = path.join(__dirname, 'user.ico') // path of y
var win
function createWindow() {
win = new BrowserWindow({ width: 600, height: 600, icon: iconpath })
win.loadURL(url.format({
pathname: path.join(__dirname, 'index.html'),
}))
var appIcon = new Tray(iconpath)
var contextMenu = Menu.buildFromTemplate([
{
label: 'Show App', click: function () {
win.show()
}
},
{
label: 'Quit', click: function () {
app.isQuiting = true
app.quit()
}
}
])
appIcon.setContextMenu(contextMenu)
win.on('close', function (event) {
win = null
})
win.on('minimize', function (event) {
event.preventDefault()
win.hide()
})
win.on('show', function () {
appIcon.setHighlightMode('always')
})
}
app.on('ready', createWindow)
答案 2 :(得分:4)
上述答案的补充-isQuiting
标志也值得在应用程序的before-quit
回调中设置。这样,如果操作系统或用户以其他方式(例如,通过Macos Dock任务栏的quit命令。完整的Typescript友好代码段:
import {app, BrowserWindow, Tray, Menu} from 'electron';
import * as path from 'path';
let window;
let isQuiting;
let tray;
app.on('before-quit', function () {
isQuiting = true;
});
app.on('ready', () => {
tray = new Tray(path.join(__dirname, 'tray.png'));
tray.setContextMenu(Menu.buildFromTemplate([
{
label: 'Show App', click: function () {
window.show();
}
},
{
label: 'Quit', click: function () {
isQuiting = true;
app.quit();
}
}
]));
window = new BrowserWindow({
width: 850,
height: 450,
show: false,
});
window.on('close', function (event) {
if (!isQuiting) {
event.preventDefault();
window.hide();
event.returnValue = false;
}
});
});
答案 3 :(得分:0)
尝试最小化事件而不是隐藏。
var BrowserWindow = require('browser-window'),
var mainWindow = new BrowserWindow({
width: 850,
height: 450,
title: "TEST",
icon:'./icon.png'
});
mainWindow.on('minimize',function(event){
event.preventDefault();
mainWindow.minimize();
});
mainWindow.on('close', function (event) {
event.preventDefault();
mainWindow.minimize();
return false;
});
这对我有用。
hide()
正在关闭窗口。
答案 4 :(得分:0)
一种比使用标志更好的方式,对于那些不想更改minimize
行为的人而言:
通常只使用close
隐藏mainWindow.hide()
事件上的窗口
mainWindow.on('close', function (event) {
event.preventDefault();
mainWindow.hide();
});
然后调用mainWIndow.destroy()
强制关闭窗口。它还保证执行closed
事件处理程序。
强制关闭窗口,不会在网页上发出unload和beforeunload事件,也不会在该窗口上发出close事件,但它保证将发出close事件。
var contextMenu = Menu.buildFromTemplate([
{ label: 'Show App', click: function(){
mainWindow.show();
} },
{ label: 'Quit', click: function(){
mainWindow.destroy();
app.quit();
} }
]);
答案 5 :(得分:0)
我分享我的 Sketch,最小化隐藏在任务栏图标上,菜单选项右键单击图标以恢复/关闭。使用 websocket/http 服务器..
//const {app, BrowserWindow} = require('electron');
const {app, BrowserWindow, Tray, Menu} = require('electron');
const myip = require('quick-local-ip');
const express = require('express');
const WebSocket = require('ws');
const bodyParser = require('body-parser');
const path = require('path')
// Config
const Config = {
http_port: '8080',
socket_port: '3030'
};
var iconpath = path.join(__dirname, 'rfid.png') // path of y
// Http server
const _app = express();
const server = require('http').Server(_app);
server.listen(Config.http_port);
// WSS server
const wss = new WebSocket.Server({port: Config.socket_port});
// Console print
console.log('[SERVER]: WebSocket on: ' + myip.getLocalIP4() + ':' + Config.socket_port); // print websocket ip address
console.log('[SERVER]: HTTP on: ' + myip.getLocalIP4() + ':' + Config.http_port); // print web server ip address
// 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 mainWindow;
let window;
let isQuiting;
let tray;
function createWindow() {
mainWindow = new BrowserWindow({
width: 1200,
height: 800,
acceptFirstMouse: true,
autoHideMenuBar: false,
useContentSize: true,
});
var appIcon = new Tray(iconpath);
// mainWindow.loadURL('index.html')
mainWindow.loadURL('http://localhost:8080');
mainWindow.focus();
// mainWindow.setFullScreen(true);
// Open the DevTools.
mainWindow.webContents.openDevTools();
var contextMenu = Menu.buildFromTemplate([
{
label: 'Show App', click: function () {
mainWindow.show()
}
},
{
label: 'Quit', click: function () {
app.isQuiting = true
app.quit()
}
}
])
appIcon.setContextMenu(contextMenu)
// Emitted when the window is closed.
mainWindow.on('close', function (event) {
mainWindow = null
});
mainWindow.on('minimize', function (event) {
event.preventDefault()
mainWindow.hide()
});
mainWindow.on('show', function () {
appIcon.setHighlightMode('always')
})
}
app.on('ready', createWindow)
// Quit when all windows are closed.
app.on('window-all-closed', function () {
// On OS X it is common for applications and their menu bar
// to stay active until the user quits explicitly with Cmd + Q
if (process.platform !== 'darwin') {
app.quit()
}
})
app.on('activate', function () {
// On OS X it's common to re-create a window in the app when the
// dock icon is clicked and there are no other windows open.
if (mainWindow === null) {
createWindow()
}
})
/**
* EXPRESS
*/
_app.use(bodyParser.urlencoded({
extended: false
}));
_app.use('/assets', express.static(__dirname + '/www/assets'))
_app.get('/', function (req, res) {
res.sendFile(__dirname + '/www/index.html');
});
/**
* WEBSOCKET
*/
wss.getUniqueID = function () {
function s4() {
return Math.floor((1 + Math.random()) * 0x10000).toString(16).substring(1);
}
return s4() + s4() + '-' + s4();
};
wss.on('connection', function connection(ws, req) {
ws.id = wss.getUniqueID();
console.log('[SERVER]: Client Connected. ID=', ws.id);
ws.on('close', function close() {
console.log('[SERVER]: Client disconnected.');
});
ws.on('message', function incoming(recieveData) {
console.log('[SERVER] Message:', recieveData);
// Example use
// send(recieveData);
sendAll(recieveData);
});
// Send back to client
function send(data) {
data = JSON.stringify(data);
ws.send(data);
}
// Send to all clients
function sendAll(data) {
data = JSON.stringify(data);
wss.clients.forEach(function each(client) {
client.send(data);
});
}
});
答案 6 :(得分:0)
这是用 NW.js 标记的,因为所有其他答案都是针对 Electron 的,所以我想我想展示一下 NW.js 中的一切总是容易得多。此处设置了一个简单的演示存储库:
只需下载并运行 npm install && npm start
。