我正在尝试实现 .ipynb 笔记本中的链接触发事件并在 JupyterLab 中的拆分/并排视图中打开链接文档的功能。具体来说,我使用自定义插件来侦听和处理任何链接的点击事件。
场景:
用户单击笔记本中的链接(例如“计划参考”)。 这应该向自定义 JupyterLab 插件发送一个事件,然后该插件在 JupyterLab 界面中的拆分/并排视图中打开链接的文档。
这是我在笔记本中使用的用于触发事件的 Python 代码:
from ipykernel.comm import Comm
from IPython import get_ipython
# Registering the comm target
def comm_target(comm, open_msg):
@comm.on_msg
def _recv(msg):
print("Message received:", msg)
get_ipython().kernel.comm_manager.register_target('schedule_reference_link', comm_target)
# Creating a Comm object
comm = Comm(target_name='schedule_reference_link')
# Function to handle button click
def on_schedule_reference_clicked(b):
print('Clicked')
comm.send(data={'event': 'schedule_ref_event', 'data': 'https://example.com'})
schedule_reference = Button(description="Schedule Reference")
schedule_reference.on_click(on_schedule_reference_clicked)
在JupyterLab插件端,我使用以下代码来监听事件:
const kernel = app.serviceManager.sessions.running().next().value.kernel;
const comm = kernel.createComm('schedule_reference_link');
comm.onMsg = (msg: { content: { data: any; }; }) => {
const eventData = msg.content.data;
if (eventData.event === 'schedule_ref_event') {
console.log('Event received:', eventData.data); // supposed to capture event data from ipynb
}
};
问题如下 虽然 comm.send() 函数似乎在 Python 端成功执行,但我无法在自定义 JupyterLab 插件中捕获任何事件。 JupyterLab 插件的 onMsg 处理程序中没有记录或接收任何事件数据。
我的问题是
任何类似实施的指导或示例将不胜感激!
您不需要使用 comm(例如,from ipykernel.comm import Comm 或 kernel.createComm())在 JupyterLab 扩展和 .ipynb 笔记本之间进行通信。有一种更简单、更有效的方法可以仅使用 JavaScript 来实现此目的。
您可以使用一行 JavaScript 来触发笔记本中的事件,而不是通过通信来设置通信。例如,您可以将此行添加到 .ipynb 文件中的按钮单击事件中:
window.jupyterapp.commands.execute('jlab-render:voila');
然后,在您的 JupyterLab 扩展中,您可以使用以下方法处理此事件:
定义您的自定义命令:
const command = 'xyz';
(window as any).jupyterlabCommands = commands;
commands.addCommand(command, {
label: 'Your Custom Label',
caption: 'Your Custom Caption',
execute: async (patharg) => {
if (window.parent && (window.parent as any).jupyterlabCommands) {
await (window.parent as any).jupyterlabCommands.execute('docmanager:open', {
path: patharg,
factory: 'notebook', // or 'voilad' based on your requirement
options: {
mode: 'split-right' // 'split-left' or other modes as needed
}
});
await (window.parent as any).jupyterlabCommands.execute('notebook:render-with-voila', notebook);
}
}
});
解释:在本例中,notebook:render-with-voila 是由渲染笔记本的 Voilà 扩展提供的命令。您可以参考 Voilà 仪表板扩展中提供的更多选项进行自定义。
这样,您可以避免复杂的通信,并使用简单的 JavaScript 命令将 Voilà 渲染或其他操作直接集成到您的 JupyterLab 插件中。