{
"cells": [
{
"cell_type": "markdown",
"metadata": {},
"source": [
"# 可交互图像\n",
"\n",
"翻译创建一个带有SVG叠加层的图像,该图像处理鼠标事件并产生图像坐标。它也是无闪烁图像更新的最佳选择。如果源URL的变化速度比浏览器加载图像的速度快,那么一些图像将被简单地跳过。因此,反复更新图像源将自动适应可用带宽。有关示例,请参见[OpenCV Webcam](https://github.com/zauberzeug/nicegui/tree/main/examples/opencv_webcam/main.py)。"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"翻译鼠标事件处理程序通过包含以下内容的鼠标事件参数进行调用:\n",
"\n",
"- `type`(JavaScript事件的名称)\n",
"- `image_x` 和 `image_y`(以像素为单位的图像坐标)\n",
"- `button` 和 `buttons`(来自JavaScript事件的鼠标按钮编号),以及\n",
"- `alt`、`ctrl`、`meta` 和 `shift`(来自JavaScript事件的修饰键)\n",
"\n",
"您也可以传递宽度和高度的元组代替图像源。这将创建一个给定大小的空白图像。\n",
"\n",
"- `source`: 图像的来源;可以是URL、本地文件路径、`base64` 字符串或者仅仅是图像大小\n",
"- `content`: 应该叠加的SVG内容;视口具有与图像相同的尺寸\n",
"- `size`: 图像的大小(宽度、高度)以像素为单位;仅在未设置 `source` 时使用\n",
"- `on_mouse`: 鼠标事件的回调函数(包含以像素为单位的图像坐标 `image_x` 和 `image_y`)\n",
"- `events`: 要订阅的JavaScript事件列表(默认值:`['click']`)\n",
"- `cross`: 是否显示十字准线或颜色字符串(默认值:`False`)"
]
},
{
"cell_type": "code",
"execution_count": 1,
"metadata": {},
"outputs": [],
"source": [
"from nicegui import events, ui\n",
"\n",
"def mouse_handler(e: events.MouseEventArguments):\n",
" color = 'SkyBlue' if e.type == 'mousedown' else 'SteelBlue'\n",
" ii.content += f''\n",
" ui.notify(f'{e.type} at ({e.image_x:.1f}, {e.image_y:.1f})')\n",
"\n",
"src = 'https://picsum.photos/id/565/640/360'\n",
"ii = ui.interactive_image(src, on_mouse=mouse_handler, events=['mousedown', 'mouseup'], cross=True)\n",
"\n",
"# ui.run()"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"## 嵌套元素\n",
"\n",
"您可以在交互式图像内部嵌套元素。使用Tailwind类,如 `\"absolute top-0 left-0\"`,可以相对于图像绝对定位标签。当然,也可以使用普通的CSS来完成。"
]
},
{
"cell_type": "code",
"execution_count": 2,
"metadata": {},
"outputs": [],
"source": [
"from nicegui import ui\n",
"\n",
"with ui.interactive_image('https://picsum.photos/id/147/640/360'):\n",
" ui.button(on_click=lambda: ui.notify('thumbs up'), icon='thumb_up') \\\n",
" .props('flat fab color=white') \\\n",
" .classes('absolute bottom-0 left-0 m-2')\n",
"\n",
"# ui.run()"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"## 强制重新加载\n",
"您可以通过调用 `force_reload` 方法来强制图像重新加载。它将在图像URL后附加一个时间戳,这将使浏览器重新加载图像。"
]
},
{
"cell_type": "code",
"execution_count": 3,
"metadata": {},
"outputs": [
{
"data": {
"text/plain": [
""
]
},
"execution_count": 3,
"metadata": {},
"output_type": "execute_result"
}
],
"source": [
"from nicegui import ui\n",
"\n",
"img = ui.interactive_image('https://picsum.photos/640/360').classes('w-64')\n",
"\n",
"ui.button('Force reload', on_click=img.force_reload)\n",
"\n",
"# ui.run()"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"## 空白画布\n",
"您也可以创建一个给定大小的空白画布。如果您想在不加载背景图像的情况下绘制某些内容,这将非常有用。"
]
},
{
"cell_type": "code",
"execution_count": 4,
"metadata": {},
"outputs": [
{
"data": {
"text/plain": [
""
]
},
"execution_count": 4,
"metadata": {},
"output_type": "execute_result"
}
],
"source": [
"from nicegui import ui\n",
"\n",
"ui.interactive_image(\n",
" size=(800, 600), cross=True,\n",
" on_mouse=lambda e: e.sender.set_content(f'''\n",
" \n",
" '''),\n",
").classes('w-64 bg-blue-50')\n",
"\n",
"# ui.run()"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"## 加载完成事件\n",
"您可以监听 `\"loaded\"` 事件,以便知道图像何时已加载完成。"
]
},
{
"cell_type": "code",
"execution_count": 5,
"metadata": {},
"outputs": [
{
"data": {
"text/plain": [
""
]
},
"execution_count": 5,
"metadata": {},
"output_type": "execute_result"
}
],
"source": [
"import time\n",
"from nicegui import ui\n",
"\n",
"ii = ui.interactive_image('https://picsum.photos/640/360')\n",
"ii.on('loaded', lambda e: ui.notify(f'loaded {e.args}'))\n",
"ui.button('Change Source', on_click=lambda: ii.set_source(f'https://picsum.photos/640/360?time={time.time()}'))\n",
"\n",
"# ui.run()"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"## 十字准线\n",
"您可以通过传递 `cross=True` 来显示十字准线。您还可以通过传递颜色字符串来更改十字准线的颜色。"
]
},
{
"cell_type": "code",
"execution_count": 6,
"metadata": {},
"outputs": [
{
"data": {
"text/plain": [
""
]
},
"execution_count": 6,
"metadata": {},
"output_type": "execute_result"
}
],
"source": [
"from nicegui import ui\n",
"\n",
"ui.interactive_image('https://picsum.photos/id/565/640/360', cross='red')\n",
"\n",
"# ui.run()"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": []
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {},
"outputs": [],
"source": []
}
],
"metadata": {
"kernelspec": {
"display_name": "py311",
"language": "python",
"name": "python3"
},
"language_info": {
"codemirror_mode": {
"name": "ipython",
"version": 3
},
"file_extension": ".py",
"mimetype": "text/x-python",
"name": "python",
"nbconvert_exporter": "python",
"pygments_lexer": "ipython3",
"version": "3.11.7"
}
},
"nbformat": 4,
"nbformat_minor": 2
}