解决白屏问题
在electron中使用 loadURL来加载窗口,会出现短暂的白屏,从给出的图片可以看出,我在mainjs中通过loadUrl加载了两个窗口
mainWindow.loadURL(resolveHtmlPath('index.html'));
在主程序在app.whenReady()准备完毕的时候,我创建了一个窗口,监听到渲染进程的动作会
app
.whenReady()
.then(() => {
createWindow()
app.on('activate', () => {
if (mainWindow === null) createWindow();
});
})
.catch(console.log);
const createWindow = async () => {
mainWindow = new BrowserWindow({
// show: false,
width: 1024,
height: 728,
transparent: true,
icon: getAssetPath('icon.png'),
webPreferences: {
preload: app.isPackaged
? path.join(__dirname, 'preload.js')
: path.join(__dirname, '../../.erb/dll/preload.js'),
},
});
mainWindow.loadURL(resolveHtmlPath('index.html'));
//监听渲染进程事件
ipcMain.on('ipc-example', async (event, arg) => {
const msgTemplate = (pingPong: string) => `IPC test: ${pingPong}`;
console.log(msgTemplate(arg),'收到渲染进程信息');
showNotification()
// event.reply('ipc-example', msgTemplate('pong'));
});
const showNotification = ()=>{
dialogWindow = new BrowserWindow({
width:digalogWidth,
height:dialogHeight,
x:width-digalogWidth,
y:height-dialogHeight,
skipTaskbar:true,
});
dialogWindow.loadURL(resolveHtmlPath('dialog.html'));
}
}
两个窗口都会被触发,并且载入html,所以这段时间会进入短暂的白屏,我们可以通过以下操作来解决
使用 ready-to-show 事件解决
在加载页面时,渲染进程第一次完成绘制时,如果窗口还没有被显示,渲染进程会发出
ready-to-show事件 。 在此事件后显示窗口将没有白屏
const dialogWindow = new BrowserWindow({ show: false })
dialogWindow.once('ready-to-show', () => {
dialogWindow.show()
})
对于官方给的以上的解释其实有点模糊,直白的理解就是show:false设置的是不自动显示,我们通过dialogwindow.show()和hide()来手动控制窗口的显示和隐藏,
窗口加载时候自带了一个ready-to-show 事件,这个事件是窗口已经载入html可以展示的状态,在这条件下再去通过show来控制窗口的显示,就能解决加载时候的白屏问题.
解决ipcRenderer报错提示
当我使用ipcRenderer来声明一个新的监听事件的时候 发现sendMessage 是'ipc-example'的时候是正常的,但是
不给我新增新的事件,并且会出现提示
window.electron.ipcRenderer.sendMessage('ipc-example');
即使我定义了监听事件,错误仍然存在
ipcMain.on('close-msg', async (event, arg) => {
console.log('收到渲染进程信息');
dialogWindow!.hide();
});
后续发现在preload.ts中,定义了一个名为 Channels 的类型别名,它的值是 'ipc-example'。
给Channels增加多几个类型就可以解决ts的提示问题
export type Channels = 'ipc-example' | 'close-msg' | 'open-msg';
解决主进程和渲染进程通信
我想实现的主要思路:
1.渲染进程设置事件
2.发送时间给主进程
3.主进程根据渲染进程设置的时间打开窗口
监听TimePicker改变 发送ipc事件
const onChange = (time: Dayjs, timeString: string) => {
console.log(time.format('HH:mm'));
window.electron.ipcRenderer.sendMessage('change-time', time.format('HH:mm'));
};
return (
<div>
<div className="Hello">
<img width="200" alt="icon" src={icon} onClick={showLoading} />
</div>
<h1>Choose the time:</h1>
<Space wrap>
<TimePicker onChange={onChange} defaultValue={dayjs('18:00', 'HH:mm')} size="large" />
</Space>
</div>
);
主进程接收事件并且设置定时器
这里我希望根据我设置的时间来打开窗口,所以要用interval轮询,对窗口进行show操作
ipcMain.on('change-time', async (event, arg) => {
timeString = arg
if (myTimer !== null) {
clearInterval(myTimer);
myTimer = null;
}
myTimer = setInterval(() => {
const now = dayjs().format('HH:mm');
console.log('now', now);
console.log('timeString', timeString);
if(now==timeString){
clearInterval(myTimer!);
dialogWindow!.show();
setTimeout(() => {
dialogWindow!.hide();
}, 22000);
}
}, 5000);
});