瀏覽代碼

feat: `put_buttons()` onclick parameter can use list type

wangweimin 5 年之前
父節點
當前提交
95680dab79
共有 3 個文件被更改,包括 32 次插入15 次删除
  1. 30 9
      pywebio/output.py
  2. 1 3
      pywebio/session/coroutinebased.py
  3. 1 3
      pywebio/session/threadbased.py

+ 30 - 9
pywebio/output.py

@@ -40,7 +40,7 @@ r"""输出内容到用户浏览器
 import io
 import logging
 from base64 import b64encode
-from collections.abc import Mapping
+from collections.abc import Mapping, Sequence
 from functools import wraps
 
 from .io_ctrl import output_register_callback, send_msg, OutputReturn, safely_destruct_output_when_exp
@@ -423,11 +423,15 @@ def put_buttons(buttons, onclick, small=None, scope=Scope.Current, position=Outp
         * tuple or list: ``(label, value)``
         * 单值: 此时label和value使用相同的值
 
-    :type onclick: Callable or Coroutine
-    :param onclick: 按钮点击回调函数. ``onclick`` 可以是普通函数或者协程函数.
-       函数签名为 ``onclick(btn_value)``.
-       当按钮组中的按钮被点击时,``onclick`` 被调用,并传入被点击的按钮的 ``value`` 值。
-       可以使用 ``functools.partial`` 来在 ``onclick`` 中保存更多上下文信息 。
+    :type onclick: Callable / list
+    :param onclick: 按钮点击回调函数. ``onclick`` 可以是函数或者函数组成的列表.
+
+       ``onclick`` 为函数时, 签名为 ``onclick(btn_value)``. ``btn_value`` 为被点击的按钮的 ``value`` 值
+
+       ``onclick`` 为列表时,列表内函数的签名为 ``func()``. 此时,回调函数与 ``buttons`` 一一对应
+
+       | Tip: 可以使用 ``functools.partial`` 来在 ``onclick`` 中保存更多上下文信息.
+       | Note: 当使用基于协程的会话实现时,回调函数可以使用协程函数.
     :param bool small: 是否显示小号按钮,默认为False
     :param int scope, position: 与 `put_text` 函数的同名参数含义一致
     :param callback_options: 回调函数的其他参数。根据选用的 session 实现有不同参数
@@ -444,14 +448,31 @@ def put_buttons(buttons, onclick, small=None, scope=Scope.Current, position=Outp
 
         from functools import partial
 
-        def edit_row(choice, id):
+        def row_action(choice, id):
             put_text("You click %s button with id: %s" % (choice, id))
 
-        put_buttons(['edit', 'delete'], onclick=partial(edit_row, id=1))
+        put_buttons(['edit', 'delete'], onclick=partial(row_action, id=1))
 
+        def edit():
+            ...
+        def delete():
+            ...
+        put_buttons(['edit', 'delete'], onclick=[edit, delete])
     """
     btns = _format_button(buttons)
-    callback_id = output_register_callback(onclick, **callback_options)
+
+    if isinstance(onclick, Sequence):
+        assert len(btns) == len(onclick), "`onclick` and `buttons` must be same length."
+        onclick = {btn['value']: callback for btn, callback in zip(btns, onclick)}
+
+    def click_callback(btn_val):
+        if isinstance(onclick, dict):
+            func = onclick.get(btn_val, lambda: None)
+            return func()
+        else:
+            return onclick(btn_val)
+
+    callback_id = output_register_callback(click_callback, **callback_options)
     spec = _get_output_spec('buttons', callback_id=callback_id, buttons=btns, small=small,
                             scope=scope, position=position)
 

+ 1 - 3
pywebio/session/coroutinebased.py

@@ -175,11 +175,9 @@ class CoroutineBasedSession(Session):
         """ 向Session注册一个回调函数,返回回调id
 
         :type callback: Callable or Coroutine
-        :param callback: 回调函数. 可以是普通函数或者协程函数. 函数签名为 ``callback(data)``.
+        :param callback: 回调函数. 函数签名为 ``callback(data)``. ``data`` 参数为回调事件的值
         :param bool mutex_mode: 互斥模式。若为 ``True`` ,则在运行回调函数过程中,无法响应同一组件的新点击事件,仅当 ``callback`` 为协程函数时有效
         :return str: 回调id.
-            CoroutineBasedSession 保证当收到前端发送的事件消息 ``{event: "callback",coro_id: 回调id, data:...}`` 时,
-            ``callback`` 回调函数被执行, 并传入事件消息中的 ``data`` 字段值作为参数
         """
 
         async def callback_coro():

+ 1 - 3
pywebio/session/threadbased.py

@@ -250,9 +250,7 @@ class ThreadBasedSession(Session):
     def register_callback(self, callback, serial_mode=False):
         """ 向Session注册一个回调函数,返回回调id
 
-        Session需要保证当收到前端发送的事件消息 ``{event: "callback",task_id: 回调id, data:...}`` 时,
-        ``callback`` 回调函数被执行, 并传入事件消息中的 ``data`` 字段值作为参数
-
+        :param Callable callback: 回调函数. 函数签名为 ``callback(data)``. ``data`` 参数为回调事件的值
         :param bool serial_mode: 串行模式模式。若为 ``True`` ,则对于同一组件的点击事件,串行执行其回调函数
         """
         assert (not iscoroutinefunction(callback)) and (not isgeneratorfunction(callback)), ValueError(