通用事件#

大多数 UI 元素都带有预定义的事件。例如,演示中的 “A” 这样的 ui.button 有一个 on_click 参数,它期望一个协程或函数。但是,您也可以使用 on 方法来注册一个通用事件处理器,就像 “B” 那样。这允许您为 JavaScript 和 Quasar 支持的任何事件注册处理器。

例如,即使 ui.button 没有 on_mousemove 参数,您也可以像 “C” 那样为 mousemove 事件注册处理器。有些事件,比如 mousemove,会非常频繁地触发。为了避免性能问题,您可以使用 throttle 参数,以便每 throttle 秒只调用一次处理器(“D”)。

通用事件处理器可以是同步的或异步的,并且可以选择性地接受 GenericEventArguments 作为参数(“E”)。您还可以指定应该将 JavaScript 或 Quasar 事件的哪些属性传递给处理器(“F”)。这可以减少需要在服务器和客户端之间传输的数据量。

在这里,您可以找到有关支持的事件的更多信息:

from nicegui import ui

with ui.row():
    ui.button('A', on_click=lambda: ui.notify('You clicked the button A.'))
    ui.button('B').on('click', lambda: ui.notify('You clicked the button B.'))
with ui.row():
    ui.button('C').on('mousemove', lambda: ui.notify('You moved on button C.'))
    ui.button('D').on('mousemove', lambda: ui.notify('You moved on button D.'), throttle=0.5)
with ui.row():
    ui.button('E').on('mousedown', lambda e: ui.notify(e))
    ui.button('F').on('mousedown', lambda e: ui.notify(e), ['ctrlKey', 'shiftKey'])

# ui.run()

指定事件属性#

一个字符串列表命名了 JavaScript 事件对象的属性:

ui.button().on('click', handle_click, ['clientX', 'clientY'])

一个空列表请求没有属性:

ui.button().on('click', handle_click, [])

None 表示所有属性(默认):

ui.button().on('click', handle_click, None)

如果事件像 QTable 的 "row-click"(evt, row, index)=> void 那样调用多个参数,您可以定义一个参数定义列表:

ui.table(...).on('rowClick', handle_click, [[], ['name'], None])

在此示例中,"row-click" 事件将省略第一个 evt 参数的所有参数,仅发送 row 参数的 "name" 属性,并发送完整的 index

如果检索到的事件参数列表长度为 1,则参数会自动解包。因此,您可以写:

ui.button().on('click', lambda e: print(e.args['clientX'], flush=True))

而不是:

ui.button().on('click', lambda e: print(e.args[0]['clientX'], flush=True))

请注意,默认情况下,会发送所有参数的所有可 JSON 序列化的属性。这样做是为了简化注册新事件和发现它们的属性。如果带宽有问题,应该将参数限制在服务器实际需要的内容上。

from nicegui import ui

columns = [
    {'name': 'name', 'label': 'Name', 'field': 'name'},
    {'name': 'age', 'label': 'Age', 'field': 'age'},
]
rows = [
    {'name': 'Alice', 'age': 42},
    {'name': 'Bob', 'age': 23},
]
ui.table(columns, rows, 'name').on('rowClick', ui.notify, [[], ['name'], None])

# ui.run()
<nicegui.elements.table.Table at 0x7fb6f837bbb0>

修饰符#

您还可以包含键修饰符(输入 “A” 中所示)、修饰符组合(输入 “B” 中所示)和事件修饰符(输入 “C” 中所示)。

from nicegui import ui

with ui.row():
    ui.input('A').classes('w-12').on('keydown.space', lambda: ui.notify('You pressed space.'))
    ui.input('B').classes('w-12').on('keydown.y.shift', lambda: ui.notify('You pressed Shift+Y'))
    ui.input('C').classes('w-12').on('keydown.once', lambda: ui.notify('You started typing.'))

# ui.run()

自定义事件#

使用 emitEvent(...) 从 JavaScript 发出自定义事件非常简单,可以使用 ui.on(...) 进行监听。如果您希望在 JavaScript 中发生某事时调用 Python 代码,这可能会很有用。在这个例子中,我们正在监听浏览器标签页的 visibilitychange 事件。

from nicegui import ui

tabwatch = ui.checkbox('Watch browser tab re-entering')
ui.on('tabvisible', lambda: ui.notify('Welcome back!') if tabwatch.value else None)
ui.add_head_html('''
    <script>
    document.addEventListener('visibilitychange', () => {
        if (document.visibilityState === 'visible') {
            emitEvent('tabvisible');
        }
    });
    </script>
''')

# ui.run()

纯 JavaScript 事件#

您还可以使用 on 方法注册纯 JavaScript 事件处理器。如果您想在不向服务器发送任何数据的情况下调用 JavaScript 代码,这可能会很有用。在这个例子中,我们正在使用 navigator.clipboard API 将字符串复制到剪贴板。

from nicegui import ui

ui.button('Copy to clipboard') \
    .on('click', js_handler='''() => {
        navigator.clipboard.writeText("Hello, NiceGUI!");
    }''')

# ui.run()
<nicegui.elements.button.Button at 0x7fb6f837bc10>