소스 검색

doc: update doc for `put_table()`

wangweimin 5 년 전
부모
커밋
e10f32c768
4개의 변경된 파일71개의 추가작업 그리고 11개의 파일을 삭제
  1. BIN
      docs/assets/put_table.png
  2. 23 4
      docs/guide.rst
  3. 41 4
      pywebio/output.py
  4. 7 3
      test/template.py

BIN
docs/assets/put_table.png


+ 23 - 4
docs/guide.rst

@@ -131,6 +131,25 @@ PyWebIO提供了一些便捷函数来输出表格、链接等格式::
 
 PyWebIO提供的全部输出函数请见 :doc:`pywebio.output </output>` 模块
 
+组合输出
+^^^^^^^^^^^^^^
+
+`put_table() <pywebio.output.put_table>` 还支持以 ``put_xxx`` 类型的输出函数作为单元格内容::
+
+    put_table([
+        ['Type', 'Content'],
+        ['html', 'X<sup>2</sup>'],
+        ['text', put_text('<hr/>')],
+        ['buttons', put_buttons(['A', 'B'], onclick=...)],
+        ['markdown', put_markdown('`Awesome PyWebIO!`')],
+        ['file', put_file('hello.text', b'')],
+        ['table', put_table([['A', 'B'], ['C', 'D']])]
+    ])
+
+上例显示效果如下:
+
+.. image:: /assets/put_table.png
+
 事件回调
 ^^^^^^^^^^^^^^
 
@@ -146,12 +165,12 @@ PyWebIO把程序与用户的交互分成了输入和输出两部分:输入函
 
     put_table([
         ['Idx', 'Actions'],
-        [1, table_cell_buttons(['edit', 'delete'], onclick=partial(edit_row, row=1))],
-        [2, table_cell_buttons(['edit', 'delete'], onclick=partial(edit_row, row=2))],
-        [3, table_cell_buttons(['edit', 'delete'], onclick=partial(edit_row, row=3))],
+        [1, put_buttons(['edit', 'delete'], onclick=partial(edit_row, row=1))],
+        [2, put_buttons(['edit', 'delete'], onclick=partial(edit_row, row=2))],
+        [3, put_buttons(['edit', 'delete'], onclick=partial(edit_row, row=3))],
     ])
 
-`put_table() <pywebio.output.put_table>` 的调用不会阻塞。当用户点击了某行中的按钮时,PyWebIO会自动调用相应的处理函数:
+`put_table() <pywebio.output.put_table>` 的调用不会阻塞。当用户点击了某行中的按钮时,PyWebIO会自动调用相应的回调函数:
 
 .. image:: /assets/table_onclick.*
 

+ 41 - 4
pywebio/output.py

@@ -35,19 +35,23 @@ r"""输出内容到用户浏览器
 .. autofunction:: put_file
 """
 import io
+import json
+import logging
 from base64 import b64encode
 from collections.abc import Mapping
 
-from .io_ctrl import output_register_callback, send_msg, OutputReturn
+from .io_ctrl import output_register_callback, send_msg, OutputReturn, safely_destruct_output_when_exp
 
 try:
     from PIL.Image import Image as PILImage
 except ImportError:
     PILImage = type('MockPILImage', (), dict(__init__=None))
 
+logger = logging.getLogger(__name__)
+
 __all__ = ['TOP', 'MIDDLE', 'BOTTOM', 'set_title', 'set_output_fixed_height', 'set_auto_scroll_bottom', 'set_anchor',
            'clear_before', 'clear_after', 'clear_range', 'remove', 'scroll_to', 'put_text', 'put_html',
-           'put_code', 'put_markdown', 'put_table', 'table_cell_buttons', 'put_buttons', 'put_image', 'put_file']
+           'put_code', 'put_markdown', 'put_table', 'table_cell_buttons', 'put_buttons', 'put_image', 'put_file', ]
 
 TOP = 'top'
 MIDDLE = 'middle'
@@ -248,11 +252,12 @@ def put_markdown(mdcontent, strip_indent=0, lstrip=False, anchor=None, before=No
     return OutputReturn(spec)
 
 
+@safely_destruct_output_when_exp('tdata')
 def put_table(tdata, header=None, span=None, anchor=None, before=None, after=None) -> OutputReturn:
     """
     输出表格
 
-    :param list tdata: 表格数据。列表项可以为 ``list`` 或者 ``dict`` , 单元格的内容可以为字符串或其他输出函数的返回值,字符串内容显示时会被当作html。
+    :param list tdata: 表格数据。列表项可以为 ``list`` 或者 ``dict`` , 单元格的内容可以为字符串或 ``put_xxx`` 类型的输出函数,字符串内容的单元格显示时会被当作html。
     :param list header: 设定表头。
        当 ``tdata`` 的列表项为 ``list`` 类型时,若省略 ``header`` 参数,则使用 ``tdata`` 的第一项作为表头。
 
@@ -265,6 +270,7 @@ def put_table(tdata, header=None, span=None, anchor=None, before=None, after=Non
 
     使用示例::
 
+        # 'Name'单元格跨2行、'Address'单元格跨2列
         put_table([
             ['Name', 'Address'],
             ['City', 'Country'],
@@ -272,15 +278,31 @@ def put_table(tdata, header=None, span=None, anchor=None, before=None, after=Non
             ['Liu', 'New York', 'America'],
         ], span={(0,0):{"row":2}, (0,1):{"col":2}})
 
+        # 单元格为 ``put_xxx`` 类型的输出函数
+        put_table([
+            ['Type', 'Content'],
+            ['html', 'X<sup>2</sup>'],
+            ['text', put_text('<hr/>')],
+            ['buttons', put_buttons(['A', 'B'], onclick=...)],
+            ['markdown', put_markdown('`Awesome PyWebIO!`')],
+            ['file', put_file('hello.text', b'')],
+            ['table', put_table([['A', 'B'], ['C', 'D']])]
+        ])
+
+        # 设置表头
         put_table([
             ['Wang', 'M', 'China'],
             ['Liu', 'W', 'America'],
         ], header=['Name', 'Gender', 'Address'])
 
+        # dict类型的表格行
         put_table([
             {"Course":"OS", "Score": "80"},
             {"Course":"DB", "Score": "93"},
         ], header=["Course", "Score"])  # or header=[("课程", "Course"), ("得分" ,"Score")]
+
+    .. versionadded:: 0.3
+       单元格的内容支持 ``put_xxx`` 类型的输出函数
     """
 
     # Change ``dict`` row table to list row table
@@ -352,7 +374,12 @@ def table_cell_buttons(buttons, onclick, **callback_options) -> str:
             ['2', table_cell_buttons(['edit', 'delete'], onclick=partial(edit_row, row=2))],
             ['3', table_cell_buttons(['edit', 'delete'], onclick=partial(edit_row, row=3))],
         ])
+
+    .. deprecated:: 0.3
+       Use :func:`put_buttons()` instead
     """
+    logger.warning("pywebio.output.table_cell_buttons() is deprecated in version 0.3 and will be removed in 1.0, "
+                   "use pywebio.output.put_buttons() instead.")
     btns = _format_button(buttons)
     callback_id = output_register_callback(onclick, **callback_options)
     tpl = '<button type="button" value="{value}" class="btn btn-primary btn-sm" ' \
@@ -376,7 +403,7 @@ def put_buttons(buttons, onclick, small=None, anchor=None, before=None, after=No
     :param onclick: 按钮点击回调函数. ``onclick`` 可以是普通函数或者协程函数.
        函数签名为 ``onclick(btn_value)``.
        当按钮组中的按钮被点击时,``onclick`` 被调用,并传入被点击的按钮的 ``value`` 值。
-       可以使用 ``functools.partial`` 来在 ``onclick`` 中保存更多上下文信息,见 `table_cell_buttons` :ref:`代码示例 <table_cell_buttons-code-sample>`
+       可以使用 ``functools.partial`` 来在 ``onclick`` 中保存更多上下文信息 。
     :param bool small: 是否显示小号按钮,默认为False
     :param str anchor, before, after: 与 `put_text` 函数的同名参数含义一致
     :param callback_options: 回调函数的其他参数。根据选用的 session 实现有不同参数
@@ -388,6 +415,16 @@ def put_buttons(buttons, onclick, small=None, anchor=None, before=None, after=No
            * serial_mode: 串行模式模式。默认为 ``False`` 。若为 ``True`` ,则运行当前点击事件时,其他所有新的点击事件都将被排队等待当前点击事件时运行完成。
              不开启 ``serial_mode`` 时,ThreadBasedSession 在新线程中执行回调函数。所以如果回调函数运行时间很短,
              可以关闭 ``serial_mode`` 来提高性能。
+
+    使用示例::
+
+        from functools import partial
+
+        def edit_row(choice, id):
+            put_text("You click %s button with id: %s" % (choice, id))
+
+        put_buttons(['edit', 'delete'], onclick=partial(edit_row, id=1))
+
     """
     btns = _format_button(buttons)
     callback_id = output_register_callback(onclick, **callback_options)

+ 7 - 3
test/template.py

@@ -82,6 +82,10 @@ def basic_output():
         ['markdown', put_markdown('`awesome PyWebIO!`\n - 1\n - 2\n - 3')],
         ['file', put_file('hello.text', b'')],
         ['image', put_image(img_data)],
+        ['table', put_table([
+            ['A', 'B'],
+            [put_markdown('`C`'), put_markdown('`D`')]
+        ])]
     ])
 
     put_text('code:')
@@ -99,9 +103,9 @@ def basic_output():
 
     put_table([
         ['Idx', 'Actions'],
-        ['1', table_cell_buttons(['edit', 'delete'], onclick=partial(edit_row, row=1))],
-        ['2', table_cell_buttons(['edit', 'delete'], onclick=partial(edit_row, row=2))],
-        ['3', table_cell_buttons(['edit', 'delete'], onclick=partial(edit_row, row=3))],
+        ['1', put_buttons(['edit', 'delete'], onclick=partial(edit_row, row=1))],
+        ['2', put_buttons(['edit', 'delete'], onclick=partial(edit_row, row=2))],
+        ['3', put_buttons(['edit', 'delete'], onclick=partial(edit_row, row=3))],
     ], anchor='table_cell_buttons')
 
     put_buttons(['A', 'B', 'C'], onclick=partial(put_text, after='put_buttons'), anchor='put_buttons')