|
@@ -0,0 +1,1884 @@
|
|
|
+# SOME DESCRIPTIVE TITLE.
|
|
|
+# Copyright (C) WangWeimin
|
|
|
+# This file is distributed under the same license as the PyWebIO package.
|
|
|
+# FIRST AUTHOR <EMAIL@ADDRESS>, 2021.
|
|
|
+#
|
|
|
+msgid ""
|
|
|
+msgstr ""
|
|
|
+"Project-Id-Version: PyWebIO 1.1.0\n"
|
|
|
+"Report-Msgid-Bugs-To: \n"
|
|
|
+"POT-Creation-Date: 2021-02-17 18:31+0800\n"
|
|
|
+"PO-Revision-Date: 2021-02-18 11:33+0800\n"
|
|
|
+"MIME-Version: 1.0\n"
|
|
|
+"Content-Type: text/plain; charset=utf-8\n"
|
|
|
+"Content-Transfer-Encoding: 8bit\n"
|
|
|
+"Generated-By: Babel 2.8.0\n"
|
|
|
+"Last-Translator: WangWeimin <wang0.618@qq.com>\n"
|
|
|
+"Language-Team: \n"
|
|
|
+"Language: zh_CN\n"
|
|
|
+"X-Generator: Poedit 2.4.2\n"
|
|
|
+
|
|
|
+#: ../../guide.rst:2
|
|
|
+msgid "User's guide"
|
|
|
+msgstr ""
|
|
|
+
|
|
|
+#: ../../guide.rst:4
|
|
|
+msgid ""
|
|
|
+"If you are familiar with web development, you may not be accustomed to the "
|
|
|
+"usage of PyWebIO described below, which is different from the traditional web "
|
|
|
+"development patton that backend implement api and frontend display content. In "
|
|
|
+"PyWebIO, you only need write code in Python."
|
|
|
+msgstr ""
|
|
|
+"如果你接触过Web开发,你可能对接下来描述的PyWebIO的用法感到不太习惯,不同于传统"
|
|
|
+"Web开发的后端实现接口、前端进行展示交互的模式,在PyWebIO中,所有的逻辑都通过编写"
|
|
|
+"Python代码实现。"
|
|
|
+
|
|
|
+#: ../../guide.rst:6
|
|
|
+msgid ""
|
|
|
+"In fact, the way of writing PyWebIO applications is more like writing a console "
|
|
|
+"program, except that the terminal here becomes a browser. Using the imperative "
|
|
|
+"API provided by PyWebIO, you can simply call ``put_text``, ``put_image``, "
|
|
|
+"``put_table`` and other functions to output text, pictures, tables and other "
|
|
|
+"content to the browser, or you can call some functions such as ``input``, "
|
|
|
+"``select``, ``file_upload`` to display different forms on the browser to get "
|
|
|
+"user input. In addition, PyWebIO also provides support for click events, "
|
|
|
+"layout, etc. PyWebIO aims to allow you to use the least code to interact with "
|
|
|
+"the user and provide a good user experience as much as possible."
|
|
|
+msgstr ""
|
|
|
+"你可以按照编写控制台程序的逻辑编写PyWebIO应用,只不过这里的终端变成了浏览器。通"
|
|
|
+"过PyWebIO提供的命令式API,\n"
|
|
|
+"你可以简单地调用 ``put_text`` 、 ``put_image`` 、 ``put_table`` 等函数输出文本、"
|
|
|
+"图片、表格等内容到浏览器,也可以调用 ``input`` 、 ``select`` 、\n"
|
|
|
+"``file_upload`` 等函数在浏览器上显示不同表单来接收用户的输入。此外PyWebIO中还提"
|
|
|
+"供了点击事件、布局等支持,让你可以使用最少的代码完成与用户的交互,\n"
|
|
|
+"并尽可能提供良好的用户体验。"
|
|
|
+
|
|
|
+#: ../../guide.rst:9
|
|
|
+msgid ""
|
|
|
+"This user guide introduces you the most of the features of PyWebIO. There is a "
|
|
|
+"demo link at the top right of the most of the example codes in this document, "
|
|
|
+"where you can preview the running effect of the code online."
|
|
|
+msgstr ""
|
|
|
+"本篇使用指南从几个方面对PyWebIO的使用进行介绍,覆盖了PyWebIO的绝大部分特性。本文"
|
|
|
+"档中大部分示例代码的右上方都有一个Demo链接,点击后可以在线预览代码的运行效果。"
|
|
|
+
|
|
|
+#: ../../guide.rst:12
|
|
|
+msgid "Input"
|
|
|
+msgstr "输入"
|
|
|
+
|
|
|
+#: ../../guide.rst:14
|
|
|
+msgid ""
|
|
|
+"The input functions are defined in the :doc:`pywebio.input </input>` module and "
|
|
|
+"can be imported using ``from pywebio.input import *``."
|
|
|
+msgstr ""
|
|
|
+"输入函数都定义在 :doc:`pywebio.input </input>` 模块中,可以使用 ``from pywebio."
|
|
|
+"input import *`` 引入。"
|
|
|
+
|
|
|
+#: ../../guide.rst:16
|
|
|
+msgid ""
|
|
|
+"When calling the input function, an input form will be popped up on the "
|
|
|
+"browser. PyWebIO's input functions is blocking (same as Python's built-in "
|
|
|
+"``input()`` function) and will not return until the form is successfully "
|
|
|
+"submitted."
|
|
|
+msgstr ""
|
|
|
+"调用输入函数会在浏览器上弹出一个输入表单来获取输入。PyWebIO的输入函数是阻塞式的"
|
|
|
+"(和Python内置的 `input` 一样),在表单被成功提交之前,输入函数不会返回。"
|
|
|
+
|
|
|
+#: ../../guide.rst:19
|
|
|
+msgid "Basic input"
|
|
|
+msgstr "基本输入"
|
|
|
+
|
|
|
+#: ../../guide.rst:21
|
|
|
+msgid "Here are some basic types of input."
|
|
|
+msgstr "首先是一些基本类型的输入。"
|
|
|
+
|
|
|
+#: ../../guide.rst:23
|
|
|
+msgid "Text input:"
|
|
|
+msgstr "文本输入:"
|
|
|
+
|
|
|
+#: ../../guide.rst:25
|
|
|
+#, python-format
|
|
|
+msgid ""
|
|
|
+"age = input(\"How old are you?\", type=NUMBER)\n"
|
|
|
+"put_text('age = %r' % age) # ..demo-only"
|
|
|
+msgstr ""
|
|
|
+
|
|
|
+#: ../../guide.rst:32
|
|
|
+msgid ""
|
|
|
+"After running the above code, the browser will pop up a text input field to get "
|
|
|
+"the input. After the user completes the input and submits the form, the "
|
|
|
+"function returns the value entered by the user."
|
|
|
+msgstr ""
|
|
|
+"这样一行代码的效果为:浏览器会弹出一个文本输入框来获取输入,在用户完成输入将表单"
|
|
|
+"提交后,函数返回用户输入的值。"
|
|
|
+
|
|
|
+#: ../../guide.rst:34
|
|
|
+msgid "Here are some other types of input functions:"
|
|
|
+msgstr "下面是一些其他类型的输入函数:"
|
|
|
+
|
|
|
+#: ../../guide.rst:36
|
|
|
+#, python-format
|
|
|
+msgid ""
|
|
|
+"# Password input\n"
|
|
|
+"password = input(\"Input password\", type=PASSWORD)\n"
|
|
|
+"put_text('password = %r' % password) # ..demo-only\n"
|
|
|
+"## ----\n"
|
|
|
+"\n"
|
|
|
+"# Drop-down selection\n"
|
|
|
+"gift = select('Which gift you want?', ['keyboard', 'ipad'])\n"
|
|
|
+"put_text('gift = %r' % gift) # ..demo-only\n"
|
|
|
+"## ----\n"
|
|
|
+"\n"
|
|
|
+"# Checkbox\n"
|
|
|
+"agree = checkbox(\"User Term\", options=['I agree to terms and conditions'])\n"
|
|
|
+"put_text('agree = %r' % agree) # ..demo-only\n"
|
|
|
+"## ----\n"
|
|
|
+"\n"
|
|
|
+"# Single choice\n"
|
|
|
+"answer = radio(\"Choose one\", options=['A', 'B', 'C', 'D'])\n"
|
|
|
+"put_text('answer = %r' % answer) # ..demo-only\n"
|
|
|
+"## ----\n"
|
|
|
+"\n"
|
|
|
+"# Multi-line text input\n"
|
|
|
+"text = textarea('Text Area', rows=3, placeholder='Some text')\n"
|
|
|
+"put_text('text = %r' % text) # ..demo-only\n"
|
|
|
+"## ----\n"
|
|
|
+"\n"
|
|
|
+"# File Upload\n"
|
|
|
+"img = file_upload(\"Select a image:\", accept=\"image/*\")\n"
|
|
|
+"if img: # ..demo-only\n"
|
|
|
+" put_image(img['content'], title=img['filename']) # ..demo-only"
|
|
|
+msgstr ""
|
|
|
+"# 密码输入\n"
|
|
|
+"password = input(\"Input password\", type=PASSWORD)\n"
|
|
|
+"put_text('password = %r' % password) # ..demo-only\n"
|
|
|
+"## ——\n"
|
|
|
+"\n"
|
|
|
+"# 下拉选择框\n"
|
|
|
+"gift = select('Which gift you want?', ['keyboard', 'ipad'])\n"
|
|
|
+"put_text('gift = %r' % gift) # ..demo-only\n"
|
|
|
+"## ——\n"
|
|
|
+"\n"
|
|
|
+"# 勾选选项\n"
|
|
|
+"agree = checkbox(\"用户协议\", options=['I agree to terms and conditions'])\n"
|
|
|
+"put_text('agree = %r' % agree) # ..demo-only\n"
|
|
|
+"## ——\n"
|
|
|
+"\n"
|
|
|
+"# 单选选项\n"
|
|
|
+"answer = radio(\"Choose one\", options=['A', 'B', 'C', 'D'])\n"
|
|
|
+"put_text('answer = %r' % answer) # ..demo-only\n"
|
|
|
+"## ——\n"
|
|
|
+"\n"
|
|
|
+"# 多行文本输入\n"
|
|
|
+"text = textarea('Text Area', rows=3, placeholder='Some text')\n"
|
|
|
+"put_text('text = %r' % text) # ..demo-only\n"
|
|
|
+"## ——\n"
|
|
|
+"\n"
|
|
|
+"# 文件上传\n"
|
|
|
+"img = file_upload(\"Select a image:\", accept=\"image/*\")\n"
|
|
|
+"if img: # ..demo-only\n"
|
|
|
+" put_image(img['content'], title=img['filename']) # ..demo-only"
|
|
|
+
|
|
|
+#: ../../guide.rst:72
|
|
|
+msgid "Parameter of input functions"
|
|
|
+msgstr "输入选项"
|
|
|
+
|
|
|
+#: ../../guide.rst:74
|
|
|
+msgid ""
|
|
|
+"There are many parameters that can be passed to the input function(for complete "
|
|
|
+"parameters, please refer to the :doc:`function document </input>`):"
|
|
|
+msgstr ""
|
|
|
+"输入函数可指定的参数非常丰富(全部参数及含义请见 :doc:`函数文档 </input>` ):"
|
|
|
+
|
|
|
+#: ../../guide.rst:76
|
|
|
+msgid ""
|
|
|
+"input('This is label', type=TEXT, placeholder='This is placeholder',\n"
|
|
|
+" help_text='This is help text', required=True)"
|
|
|
+msgstr ""
|
|
|
+
|
|
|
+#: ../../guide.rst:83 ../../guide.rst:118 ../../guide.rst:239 ../../guide.rst:540
|
|
|
+msgid "The results of the above example are as follows:"
|
|
|
+msgstr "以上代码将在浏览器上显示如下:"
|
|
|
+
|
|
|
+#: ../../guide.rst:87
|
|
|
+msgid ""
|
|
|
+"You can specify a validation function for the input by using ``validate`` "
|
|
|
+"parameter. The validation function should return ``None`` when the check "
|
|
|
+"passes, otherwise an error message will be returned:"
|
|
|
+msgstr ""
|
|
|
+"我们可以为输入指定校验函数,校验函数应在校验通过时返回None,否则返回错误消息:"
|
|
|
+
|
|
|
+#: ../../guide.rst:89
|
|
|
+#, python-format
|
|
|
+msgid ""
|
|
|
+"def check_age(p): # return None when the check passes, otherwise return the "
|
|
|
+"error message\n"
|
|
|
+" if p < 10:\n"
|
|
|
+" return 'Too young!!'\n"
|
|
|
+" if p > 60:\n"
|
|
|
+" return 'Too old!!'\n"
|
|
|
+"\n"
|
|
|
+"age = input(\"How old are you?\", type=NUMBER, validate=check_age)\n"
|
|
|
+"put_text('age = %r' % age) # ..demo-only"
|
|
|
+msgstr ""
|
|
|
+
|
|
|
+#: ../../guide.rst:102
|
|
|
+msgid ""
|
|
|
+"When the user input an illegal value, the input field is displayed as follows:"
|
|
|
+msgstr "当用户输入了不合法的值时,页面上的显示如下:"
|
|
|
+
|
|
|
+#: ../../guide.rst:106
|
|
|
+msgid ""
|
|
|
+"You can use ``code`` parameter in :func:`pywebio.input.textarea()` to make a "
|
|
|
+"code editing textarea. This feature uses `Codemirror <https://codemirror.net/"
|
|
|
+">`_ as underlying implementation. The ``code`` parameter accept the Codemirror "
|
|
|
+"options as a dict."
|
|
|
+msgstr ""
|
|
|
+":func:`pywebio.input.textarea` 还支持使用 `Codemirror <https://codemirror.net/"
|
|
|
+">`_ 实现代码风格的编辑区,只需使用 ``code`` 参数传入Codemirror支持的选项即可(最"
|
|
|
+"简单的情况是直接传入 ``code={}`` 或 ``code=True``):"
|
|
|
+
|
|
|
+#: ../../guide.rst:108
|
|
|
+msgid ""
|
|
|
+"code = textarea('Code Edit', code={\n"
|
|
|
+" 'mode': \"python\", # code language\n"
|
|
|
+" 'theme': 'darcula', # Codemirror theme. Visit https://codemirror.net/demo/"
|
|
|
+"theme.html#cobalt to get more themes\n"
|
|
|
+"}, value='import something\\n# Write your python code')\n"
|
|
|
+"put_code(code, language='python') # ..demo-only"
|
|
|
+msgstr ""
|
|
|
+
|
|
|
+#: ../../guide.rst:122
|
|
|
+msgid ""
|
|
|
+":ref:`Here <codemirror_options>` are some commonly used Codemirror options. For "
|
|
|
+"complete Codemirror options, please visit: https://codemirror.net/doc/manual."
|
|
|
+"html#config"
|
|
|
+msgstr ""
|
|
|
+":ref:`这里 <codemirror_options>` 列举了一些常用的Codemirror选项,完整的"
|
|
|
+"Codemirror选项请见:https://codemirror.net/doc/manual.html#config"
|
|
|
+
|
|
|
+#: ../../guide.rst:125
|
|
|
+msgid "Input Group"
|
|
|
+msgstr "输入组"
|
|
|
+
|
|
|
+#: ../../guide.rst:127
|
|
|
+msgid ""
|
|
|
+"PyWebIO uses input group to get multiple inputs in a single form. `pywebio."
|
|
|
+"input.input_group()` accepts a list of single input function call as parameter, "
|
|
|
+"and returns a dictionary with the ``name`` from the single input function as "
|
|
|
+"the key and the input data as the value:"
|
|
|
+msgstr ""
|
|
|
+"PyWebIO支持输入组, 返回结果为一个字典。`pywebio.input.input_group()` 接受单项输"
|
|
|
+"入组成的列表作为参数, 返回以单项输入函数中的 ``name`` 作为键、以输入数据为值的字"
|
|
|
+"典:"
|
|
|
+
|
|
|
+#: ../../guide.rst:130
|
|
|
+msgid ""
|
|
|
+"def check_age(p): # ..demo-only\n"
|
|
|
+" if p < 10: # ..demo-only\n"
|
|
|
+" return 'Too young!!' # ..demo-only\n"
|
|
|
+" if p > 60: # ..demo-only\n"
|
|
|
+" return 'Too old!!' # ..demo-only\n"
|
|
|
+" # ..demo-only\n"
|
|
|
+"data = input_group(\"Basic info\",[\n"
|
|
|
+" input('Input your name', name='name'),\n"
|
|
|
+" input('Input your age', name='age', type=NUMBER, validate=check_age)\n"
|
|
|
+"])\n"
|
|
|
+"put_text(data['name'], data['age'])"
|
|
|
+msgstr ""
|
|
|
+
|
|
|
+#: ../../guide.rst:146
|
|
|
+msgid ""
|
|
|
+"The input group also supports using ``validate`` parameter to set the "
|
|
|
+"validation function, which accepts the entire form data as parameter:"
|
|
|
+msgstr ""
|
|
|
+"输入组中同样支持使用 ``validate`` 参数设置校验函数,其接受整个表单数据作为参数:"
|
|
|
+
|
|
|
+#: ../../guide.rst:148
|
|
|
+msgid ""
|
|
|
+"def check_age(p): # single input item validation # ..demo-only\n"
|
|
|
+" if p < 10: # ..demo-only\n"
|
|
|
+" return 'Too young!!' # ..demo-only\n"
|
|
|
+" if p > 60: # ..demo-only\n"
|
|
|
+" return 'Too old!!' # ..demo-only\n"
|
|
|
+" # ..demo-only\n"
|
|
|
+"def check_form(data): # input group validation: return (input name, error msg) "
|
|
|
+"when validation fail\n"
|
|
|
+" if len(data['name']) > 6:\n"
|
|
|
+" return ('name', 'Name too long!')\n"
|
|
|
+" if data['age'] <= 0:\n"
|
|
|
+" return ('age', 'Age can not be negative!')\n"
|
|
|
+"\n"
|
|
|
+"data = input_group(\"Basic info\",[ # ..demo-only\n"
|
|
|
+" input('Input your name', name='name'), # ..demo-only\n"
|
|
|
+" input('Input your age', name='age', type=NUMBER, validate=check_age) # .."
|
|
|
+"demo-only\n"
|
|
|
+"], validate=check_form) # ..demo-only\n"
|
|
|
+"put_text(data['name'], data['age']) # ..demo-only"
|
|
|
+msgstr ""
|
|
|
+
|
|
|
+#: ../../guide.rst:171
|
|
|
+msgid ""
|
|
|
+"PyWebIO determines whether the input function is in `input_group` or is called "
|
|
|
+"alone according to whether the ``name`` parameter is passed. So when calling an "
|
|
|
+"input function alone, **do not** set the ``name`` parameter; when calling the "
|
|
|
+"input function in `input_group`, you **must** provide the ``name`` parameter."
|
|
|
+msgstr ""
|
|
|
+"PyWebIO 根据是否在输入函数中传入 ``name`` 参数来判断输入函数是在 `input_group` "
|
|
|
+"中还是被单独调用。所以当单独调用一个输入函数时, **不要** 设置 ``name`` 参数;而"
|
|
|
+"在 `input_group` 中调用输入函数时,需 **务必提供** ``name`` 参数。"
|
|
|
+
|
|
|
+#: ../../guide.rst:174
|
|
|
+msgid "Output"
|
|
|
+msgstr "输出"
|
|
|
+
|
|
|
+#: ../../guide.rst:176
|
|
|
+msgid ""
|
|
|
+"The output functions are all defined in the :doc:`pywebio.output </output>` "
|
|
|
+"module and can be imported using ``from pywebio.output import *``."
|
|
|
+msgstr ""
|
|
|
+"输出函数都定义在 :doc:`pywebio.output </output>` 模块中,可以使用 ``from "
|
|
|
+"pywebio.output import *`` 引入。"
|
|
|
+
|
|
|
+#: ../../guide.rst:178
|
|
|
+msgid ""
|
|
|
+"When output functions is called, the content will be output to the browser in "
|
|
|
+"real time. The output functions can be called at any time during the "
|
|
|
+"application lifetime."
|
|
|
+msgstr ""
|
|
|
+"调用输出函数后,内容会实时输出到浏览器,在应用的生命周期内,可以在任意时刻调用输"
|
|
|
+"出函数。"
|
|
|
+
|
|
|
+#: ../../guide.rst:181
|
|
|
+msgid "Basic Output"
|
|
|
+msgstr "基本输出"
|
|
|
+
|
|
|
+#: ../../guide.rst:183
|
|
|
+msgid "PyWebIO provides a series of functions to output text, tables, links, etc:"
|
|
|
+msgstr "PyWebIO提供了一系列函数来输出表格、链接等格式:"
|
|
|
+
|
|
|
+#: ../../guide.rst:185
|
|
|
+msgid ""
|
|
|
+"# Text Output\n"
|
|
|
+"put_text(\"Hello world!\")\n"
|
|
|
+"## ----\n"
|
|
|
+"\n"
|
|
|
+"# Table Output\n"
|
|
|
+"put_table([\n"
|
|
|
+" ['Commodity', 'Price'],\n"
|
|
|
+" ['Apple', '5.5'],\n"
|
|
|
+" ['Banana', '7'],\n"
|
|
|
+"])\n"
|
|
|
+"## ----\n"
|
|
|
+"\n"
|
|
|
+"# Markdown Output\n"
|
|
|
+"put_markdown('~~Strikethrough~~')\n"
|
|
|
+"## ----\n"
|
|
|
+"\n"
|
|
|
+"# File Output\n"
|
|
|
+"put_file('hello_word.txt', b'hello word!')\n"
|
|
|
+"## ----\n"
|
|
|
+"\n"
|
|
|
+"# PopUp Output\n"
|
|
|
+"popup('popup title', 'popup text content')"
|
|
|
+msgstr ""
|
|
|
+
|
|
|
+#: ../../guide.rst:213
|
|
|
+msgid ""
|
|
|
+"For all output functions provided by PyWebIO, please refer to the :doc:`pywebio."
|
|
|
+"output </output>` module. In addition, PyWebIO also supports data visualization "
|
|
|
+"with some third-party libraries, see :doc:`Third-party library ecology </"
|
|
|
+"libraries_support>`."
|
|
|
+msgstr ""
|
|
|
+"PyWebIO提供的全部输出函数见 :doc:`pywebio.output </output>` 模块。另外,PyWebIO"
|
|
|
+"还支持一些第三方库来进行数据可视化,参见 :doc:`第三方库生态 </"
|
|
|
+"libraries_support>` 。"
|
|
|
+
|
|
|
+#: ../../guide.rst:218
|
|
|
+msgid "Combined Output"
|
|
|
+msgstr "组合输出"
|
|
|
+
|
|
|
+#: ../../guide.rst:220
|
|
|
+msgid ""
|
|
|
+"The output functions whose name starts with ``put_`` can be combined with some "
|
|
|
+"output functions as part of the final output:"
|
|
|
+msgstr ""
|
|
|
+"函数名以 ``put_`` 开始的输出函数,可以与一些输出函数组合使用,作为最终输出的一部"
|
|
|
+"分:"
|
|
|
+
|
|
|
+#: ../../guide.rst:222
|
|
|
+msgid ""
|
|
|
+"You can pass ``put_xxx()`` calls to `put_table() <pywebio.output.put_table>` as "
|
|
|
+"cell content:"
|
|
|
+msgstr ""
|
|
|
+"`put_table() <pywebio.output.put_table>` 支持以 ``put_xxx()`` 调用作为单元格内"
|
|
|
+"容:"
|
|
|
+
|
|
|
+#: ../../guide.rst:224
|
|
|
+msgid ""
|
|
|
+"put_table([\n"
|
|
|
+" ['Type', 'Content'],\n"
|
|
|
+" ['html', put_html('X<sup>2</sup>')],\n"
|
|
|
+" ['text', '<hr/>'], # equal to ['text', put_text('<hr/>')]\n"
|
|
|
+" ['buttons', put_buttons(['A', 'B'], onclick=...)], # ..doc-only\n"
|
|
|
+" ['buttons', put_buttons(['A', 'B'], onclick=put_text)], # ..demo-only\n"
|
|
|
+" ['markdown', put_markdown('`Awesome PyWebIO!`')],\n"
|
|
|
+" ['file', put_file('hello.text', b'hello world')],\n"
|
|
|
+" ['table', put_table([['A', 'B'], ['C', 'D']])]\n"
|
|
|
+"])"
|
|
|
+msgstr ""
|
|
|
+
|
|
|
+#: ../../guide.rst:243
|
|
|
+msgid ""
|
|
|
+"Similarly, you can pass ``put_xxx()`` calls to `popup() <pywebio.output.popup>` "
|
|
|
+"as the popup content:"
|
|
|
+msgstr ""
|
|
|
+"类似地, `popup() <pywebio.output.popup>` 也可以将 ``put_xxx()`` 调用作为弹窗内"
|
|
|
+"容:"
|
|
|
+
|
|
|
+#: ../../guide.rst:245
|
|
|
+msgid ""
|
|
|
+"popup('Popup title', [\n"
|
|
|
+" put_html('<h3>Popup Content</h3>'),\n"
|
|
|
+" 'plain html: <br/>', # Equivalent to: put_text('plain html: <br/>')\n"
|
|
|
+" put_table([['A', 'B'], ['C', 'D']]),\n"
|
|
|
+" put_buttons(['close_popup()'], onclick=lambda _: close_popup())\n"
|
|
|
+"])"
|
|
|
+msgstr ""
|
|
|
+
|
|
|
+#: ../../guide.rst:256
|
|
|
+msgid ""
|
|
|
+"Other output functions that accept ``put_xxx()`` calls as parameters are "
|
|
|
+"`put_collapse() <pywebio.output.put_collapse>`, `put_scrollable() <pywebio."
|
|
|
+"output.put_scrollable>`, `put_row() <pywebio.output.put_row>`, etc. In "
|
|
|
+"addition, you can use `put_widget() <pywebio.output.put_widget>` to make your "
|
|
|
+"own output widgets that can accept ``put_xxx()`` calls. For more information, "
|
|
|
+"please refer to corresponding function documentation."
|
|
|
+msgstr ""
|
|
|
+"其他接受 ``put_xxx()`` 调用作为参数的输出函数还有 `put_collapse() <pywebio."
|
|
|
+"output.put_collapse>` 、 `put_scrollable() <pywebio.output.put_scrollable>` 、"
|
|
|
+"`put_row() <pywebio.output.put_row>` 等,此外,还可以通过 `put_widget() "
|
|
|
+"<pywebio.output.put_widget>` 自定义可接收 ``put_xxx()`` 调用的输出组件,具体用法"
|
|
|
+"请参考函数文档。"
|
|
|
+
|
|
|
+#: ../../guide.rst:258
|
|
|
+msgid ""
|
|
|
+"When using combination output, if you want to dynamically update the "
|
|
|
+"``put_xxx()`` content after it has been output, you can use the `output() "
|
|
|
+"<pywebio.output.output>` function. `output() <pywebio.output.output>` is like a "
|
|
|
+"placeholder, it can be passed in anywhere that ``put_xxx()`` can passed in. And "
|
|
|
+"after being output, the content can also be modified:"
|
|
|
+msgstr ""
|
|
|
+"使用组合输出时,如果想在内容输出后,对其中的 ``put_xxx()`` 子项进行动态修改,可"
|
|
|
+"以使用 `output() <pywebio.output.output>` 函数,\n"
|
|
|
+"`output() <pywebio.output.output>` 就像一个占位符,它可以像 ``put_xxx()`` 一样传"
|
|
|
+"入 `put_table` 、 `popup` 、 `put_widget` 等函数中作为输出的一部分,\n"
|
|
|
+"并且,在输出后,还可以对其中的内容进行修改(比如重置或增加内容):"
|
|
|
+
|
|
|
+#: ../../guide.rst:260
|
|
|
+msgid ""
|
|
|
+" hobby = output('Coding') # equal to output(put_text('Coding'))\n"
|
|
|
+" put_table([\n"
|
|
|
+" ['Name', 'Hobbies'],\n"
|
|
|
+" ['Wang', hobby] # hobby is initialized to Coding\n"
|
|
|
+" ])\n"
|
|
|
+" ## ----\n"
|
|
|
+"\n"
|
|
|
+" hobby.reset('Movie') # hobby is reset to Movie\n"
|
|
|
+" ## ----\n"
|
|
|
+" hobby.append('Music', put_text('Drama')) # append Music, Drama to hobby\n"
|
|
|
+" ## ----\n"
|
|
|
+" hobby.insert(0, put_markdown('**Coding**')) # insert the Coding into the top "
|
|
|
+"of the hobby"
|
|
|
+msgstr ""
|
|
|
+
|
|
|
+#: ../../guide.rst:279
|
|
|
+msgid "Callback"
|
|
|
+msgstr "事件回调"
|
|
|
+
|
|
|
+#: ../../guide.rst:281
|
|
|
+msgid ""
|
|
|
+"As we can see from the above, PyWebIO divides the interaction into two parts: "
|
|
|
+"input and output. The input function is blocking, a form will be displayed on "
|
|
|
+"the user's web browser when calling input function, the input function will not "
|
|
|
+"return util the user submits the form. The output function is used to output "
|
|
|
+"content to the browser in real time. The behavior of input and output is "
|
|
|
+"consistent with the console program. That's why we say PyWebIO turning the "
|
|
|
+"browser into a \"rich text terminal\". So you can write PyWebIO applications in "
|
|
|
+"script programing way."
|
|
|
+msgstr ""
|
|
|
+"从上面可以看出,PyWebIO把交互分成了输入和输出两部分:输入函数为阻塞式调用,会在"
|
|
|
+"用户浏览器上显示一个表单,在用户提交表单之前输入函数将不会返回;输出函数将内容实"
|
|
|
+"时输出至浏览器。这种交互方式和控制台程序是一致的,因此PyWebIO应用非常适合使用控"
|
|
|
+"制台程序的编写逻辑来进行开发。"
|
|
|
+
|
|
|
+#: ../../guide.rst:283
|
|
|
+msgid ""
|
|
|
+"In addition, PyWebIO also supports event callbacks: PyWebIO allows you to "
|
|
|
+"output some buttons, and the provided callback function will be executed when "
|
|
|
+"the button is clicked."
|
|
|
+msgstr ""
|
|
|
+"此外,PyWebIO还支持事件回调:PyWebIO允许你输出一些控件,当控件被点击时执行提供的"
|
|
|
+"回调函数。"
|
|
|
+
|
|
|
+#: ../../guide.rst:285
|
|
|
+msgid "This is an example:"
|
|
|
+msgstr "下面是一个例子:"
|
|
|
+
|
|
|
+#: ../../guide.rst:287
|
|
|
+#, python-format
|
|
|
+msgid ""
|
|
|
+"from functools import partial\n"
|
|
|
+"\n"
|
|
|
+"def edit_row(choice, row):\n"
|
|
|
+" put_text(\"You click %s button ar row %s\" % (choice, row))\n"
|
|
|
+"\n"
|
|
|
+"put_table([\n"
|
|
|
+" ['Idx', 'Actions'],\n"
|
|
|
+" [1, put_buttons(['edit', 'delete'], onclick=partial(edit_row, row=1))],\n"
|
|
|
+" [2, put_buttons(['edit', 'delete'], onclick=partial(edit_row, row=2))],\n"
|
|
|
+" [3, put_buttons(['edit', 'delete'], onclick=partial(edit_row, row=3))],\n"
|
|
|
+"])"
|
|
|
+msgstr ""
|
|
|
+
|
|
|
+#: ../../guide.rst:303
|
|
|
+msgid ""
|
|
|
+"The call to `put_table() <pywebio.output.put_table>` will not block. When user "
|
|
|
+"clicks a button, the corresponding callback function will be invoked:"
|
|
|
+msgstr ""
|
|
|
+"`put_table() <pywebio.output.put_table>` 的调用不会阻塞。当用户点击了某行中的按"
|
|
|
+"钮时,PyWebIO会自动调用相应的回调函数:"
|
|
|
+
|
|
|
+#: ../../guide.rst:307
|
|
|
+msgid "Of course, PyWebIO also supports outputting individual button:"
|
|
|
+msgstr "当然,PyWebIO还支持单独的按钮控件:"
|
|
|
+
|
|
|
+#: ../../guide.rst:309
|
|
|
+#, python-format
|
|
|
+msgid ""
|
|
|
+"def btn_click(btn_val):\n"
|
|
|
+" put_text(\"You click %s button\" % btn_val)\n"
|
|
|
+"put_buttons(['A', 'B', 'C'], onclick=btn_click)"
|
|
|
+msgstr ""
|
|
|
+
|
|
|
+#: ../../guide.rst:318
|
|
|
+msgid ""
|
|
|
+"After the PyWebIO session (see :ref:`Server and script mode "
|
|
|
+"<server_and_script_mode>` for more information about session) closed, the event "
|
|
|
+"callback will not work. You can call the :func:`pywebio.session.hold()` "
|
|
|
+"function at the end of the task function to hold the session, so that the event "
|
|
|
+"callback will always be available before the browser page is closed by user."
|
|
|
+msgstr ""
|
|
|
+"在PyWebIO会话(关于会话的概念见下文 :ref:`Server与script模式 "
|
|
|
+"<server_and_script_mode>` )结束后,事件回调也将不起作用,你可以在任务函数末尾处"
|
|
|
+"使用 :func:`pywebio.session.hold()` 函数来将会话保持,这样在用户关闭浏览器页面"
|
|
|
+"前,事件回调将一直可用。"
|
|
|
+
|
|
|
+#: ../../guide.rst:321
|
|
|
+msgid "Output Scope"
|
|
|
+msgstr "输出域Scope"
|
|
|
+
|
|
|
+#: ../../guide.rst:323
|
|
|
+msgid ""
|
|
|
+"PyWebIO uses the scope model to give more control to the location of content "
|
|
|
+"output. The output area of PyWebIO can be divided into different output "
|
|
|
+"domains. The output domain is called Scope in PyWebIO."
|
|
|
+msgstr ""
|
|
|
+"PyWebIO使用Scope模型来对内容输出的位置进行灵活地控制,PyWebIO的内容输出区可以划"
|
|
|
+"分出不同的输出域,PyWebIO将输出域称作 `Scope` 。"
|
|
|
+
|
|
|
+#: ../../guide.rst:325
|
|
|
+msgid ""
|
|
|
+"The output domain is a container of output content, and each output domain is "
|
|
|
+"arranged vertically, and the output domains can also be nested."
|
|
|
+msgstr "输出域为输出内容的容器,各个输出域之间上下排列,输出域也可以进行嵌套。"
|
|
|
+
|
|
|
+#: ../../guide.rst:327
|
|
|
+msgid ""
|
|
|
+"Each output function (function name like ``put_xxx()``) will output its content "
|
|
|
+"to a scope, the default is \"current scope\". \"current scope\" is determined "
|
|
|
+"by the runtime context. The output function can also manually specify the scope "
|
|
|
+"to output. The scope name is unique within the session."
|
|
|
+msgstr ""
|
|
|
+"每个输出函数(函数名形如 `put_xxx()` )都会将内容输出到一个Scope,默认为\"当前"
|
|
|
+"Scope\",\"当前Scope\"由运行时上下文确定,输出函数也可以手动指定输出到的Scope。"
|
|
|
+"Scope名在会话内唯一。"
|
|
|
+
|
|
|
+#: ../../guide.rst:331
|
|
|
+msgid "**use_scope()**"
|
|
|
+msgstr ""
|
|
|
+
|
|
|
+#: ../../guide.rst:333
|
|
|
+msgid ""
|
|
|
+"You can use `use_scope() <pywebio.output.use_scope>` to open and enter a new "
|
|
|
+"output scope, or enter an existing output scope:"
|
|
|
+msgstr ""
|
|
|
+"可以使用 `use_scope() <pywebio.output.use_scope>` 开启并进入一个新的输出域,或进"
|
|
|
+"入一个已经存在的输出域:"
|
|
|
+
|
|
|
+#: ../../guide.rst:335
|
|
|
+msgid ""
|
|
|
+"with use_scope('scope1'): # open and enter a new output: 'scope1'\n"
|
|
|
+" put_text('text1 in scope1') # output text to scope1\n"
|
|
|
+"\n"
|
|
|
+"put_text('text in parent scope of scope1') # output text to ROOT scope\n"
|
|
|
+"\n"
|
|
|
+"with use_scope('scope1'): # enter an existing scope: 'scope1'\n"
|
|
|
+" put_text('text2 in scope1') # output text to scope1"
|
|
|
+msgstr ""
|
|
|
+"with use_scope('scope1'): # 创建并进入scope 'scope1'\n"
|
|
|
+" put_text('text1 in scope1') # 输出内容到 scope1\n"
|
|
|
+"\n"
|
|
|
+"put_text('text in parent scope of scope1') # 输出内容到 ROOT scope\n"
|
|
|
+"\n"
|
|
|
+"with use_scope('scope1'): # 进入之前创建的scope 'scope1'\n"
|
|
|
+" put_text('text2 in scope1') # 输出内容到 scope1"
|
|
|
+
|
|
|
+#: ../../guide.rst:347 ../../guide.rst:368 ../../guide.rst:452
|
|
|
+msgid "The results of the above code are as follows::"
|
|
|
+msgstr "以上代码将会输出::"
|
|
|
+
|
|
|
+#: ../../guide.rst:349
|
|
|
+msgid ""
|
|
|
+"text1 in scope1\n"
|
|
|
+"text2 in scope1\n"
|
|
|
+"text in parent scope of scope1"
|
|
|
+msgstr ""
|
|
|
+
|
|
|
+#: ../../guide.rst:353
|
|
|
+msgid ""
|
|
|
+"You can use ``clear`` parameter in `use_scope() <pywebio.output.use_scope>` to "
|
|
|
+"clear the previous content in the scope:"
|
|
|
+msgstr ""
|
|
|
+"`use_scope() <pywebio.output.use_scope>` 还可以使用 `clear` 参数将scope中原有的"
|
|
|
+"内容清空:"
|
|
|
+
|
|
|
+#: ../../guide.rst:355
|
|
|
+msgid ""
|
|
|
+"with use_scope('scope2'):\n"
|
|
|
+" put_text('create scope2')\n"
|
|
|
+"\n"
|
|
|
+"put_text('text in parent scope of scope2')\n"
|
|
|
+"## ----\n"
|
|
|
+"\n"
|
|
|
+"with use_scope('scope2', clear=True): # enter the existing scope and clear the "
|
|
|
+"previous content\n"
|
|
|
+" put_text('text in scope2')"
|
|
|
+msgstr ""
|
|
|
+"with use_scope('scope2'):\n"
|
|
|
+" put_text('create scope2')\n"
|
|
|
+"\n"
|
|
|
+"put_text('text in parent scope of scope2')\n"
|
|
|
+"## ——\n"
|
|
|
+"\n"
|
|
|
+"with use_scope('scope2', clear=True): # 进入之前创建的scope2,并清空原有内容\n"
|
|
|
+" put_text('text in scope2')"
|
|
|
+
|
|
|
+#: ../../guide.rst:370
|
|
|
+msgid ""
|
|
|
+"text in scope2\n"
|
|
|
+"text in parent scope of scope2"
|
|
|
+msgstr ""
|
|
|
+
|
|
|
+#: ../../guide.rst:373
|
|
|
+msgid "`use_scope() <pywebio.output.use_scope>` can also be used as a decorator:"
|
|
|
+msgstr "`use_scope() <pywebio.output.use_scope>` 还可以作为装饰器来使用:"
|
|
|
+
|
|
|
+#: ../../guide.rst:375
|
|
|
+msgid ""
|
|
|
+"import time # ..demo-only\n"
|
|
|
+"from datetime import datetime\n"
|
|
|
+"\n"
|
|
|
+"@use_scope('time', clear=True)\n"
|
|
|
+"def show_time():\n"
|
|
|
+" put_text(datetime.now())\n"
|
|
|
+"\n"
|
|
|
+"while 1: # ..demo-only\n"
|
|
|
+" show_time() # ..demo-only\n"
|
|
|
+" time.sleep(1) # ..demo-only"
|
|
|
+msgstr ""
|
|
|
+
|
|
|
+#: ../../guide.rst:390
|
|
|
+msgid ""
|
|
|
+"When calling ``show_time()`` for the first time, a ``time`` scope will be "
|
|
|
+"created at the current position, and the current time will be output to it. And "
|
|
|
+"then every time the ``show_time()`` is called, the new content will replace the "
|
|
|
+"previous content."
|
|
|
+msgstr ""
|
|
|
+"第一次调用 ``show_time`` 时,将会在当前位置创建 ``time`` 输出域并在其中输出当前"
|
|
|
+"时间,之后每次调用 ``show_time()`` ,时间都会输出到相同的区域。"
|
|
|
+
|
|
|
+#: ../../guide.rst:392
|
|
|
+msgid ""
|
|
|
+"Scopes can be nested. At the beginning, PyWebIO applications have only one "
|
|
|
+"``ROOT`` Scope. Each time a new scope is created, the nesting level of the "
|
|
|
+"scope will increase by one level, and each time the current scope is exited, "
|
|
|
+"the nesting level of the scope will be reduced by one. PyWebIO uses the Scope "
|
|
|
+"stack to save the nesting level of scope at runtime."
|
|
|
+msgstr ""
|
|
|
+"Scope是可嵌套的,初始条件下,PyWebIO应用只有一个最顶层的 ``ROOT`` Scope。每创建"
|
|
|
+"一个新Scope,Scope的嵌套层级便会多加一层,每退出当前Scope,Scope的嵌套层级便会减"
|
|
|
+"少一层。PyWebIO使用Scope栈来保存运行时的Scope的嵌套层级。"
|
|
|
+
|
|
|
+#: ../../guide.rst:394
|
|
|
+msgid "For example, the following code will create 3 scopes:"
|
|
|
+msgstr "例如,如下代码将会创建3个Scope:"
|
|
|
+
|
|
|
+#: ../../guide.rst:396
|
|
|
+#, python-format
|
|
|
+msgid ""
|
|
|
+"with use_scope('A'):\n"
|
|
|
+" put_text('Text in scope A')\n"
|
|
|
+"\n"
|
|
|
+" with use_scope('B'):\n"
|
|
|
+" put_text('Text in scope B')\n"
|
|
|
+"\n"
|
|
|
+"with use_scope('C'):\n"
|
|
|
+" put_text('Text in scope C')\n"
|
|
|
+"\n"
|
|
|
+"put_html(\"\"\"<style> # ..demo-only\n"
|
|
|
+"#pywebio-scope-A {border: 1px solid red;} # ..demo-only\n"
|
|
|
+"#pywebio-scope-B {border: 1px solid blue;margin:2px} # ..demo-only\n"
|
|
|
+"#pywebio-scope-C {border: 1px solid green;margin-top:2px} # ..demo-only\n"
|
|
|
+"</style>\"\"\") # ..demo-only\n"
|
|
|
+"put_text() # ..demo-only\n"
|
|
|
+"put_buttons([('Put text to %s' % i, i) for i in ('A', 'B', 'C')], lambda s: "
|
|
|
+"put_text(s, scope=s)) # ..demo-only"
|
|
|
+msgstr ""
|
|
|
+
|
|
|
+#: ../../guide.rst:418
|
|
|
+msgid "The above code will generate the following Scope layout::"
|
|
|
+msgstr "以上代码将会产生如下Scope布局::"
|
|
|
+
|
|
|
+#: ../../guide.rst:420
|
|
|
+msgid ""
|
|
|
+"┌─ROOT────────────────────┐\n"
|
|
|
+"│ │\n"
|
|
|
+"│ ┌─A───────────────────┐ │\n"
|
|
|
+"│ │ Text in scope A │ │\n"
|
|
|
+"│ │ ┌─B───────────────┐ │ │\n"
|
|
|
+"│ │ │ Text in scope B │ │ │\n"
|
|
|
+"│ │ └─────────────────┘ │ │\n"
|
|
|
+"│ └─────────────────────┘ │\n"
|
|
|
+"│ │\n"
|
|
|
+"│ ┌─C───────────────────┐ │\n"
|
|
|
+"│ │ Text in scope C │ │\n"
|
|
|
+"│ └─────────────────────┘ │\n"
|
|
|
+"└─────────────────────────┘"
|
|
|
+msgstr ""
|
|
|
+
|
|
|
+#: ../../guide.rst:436
|
|
|
+msgid "**Scope related parameters of output function**"
|
|
|
+msgstr "**输出函数的scope相关参数**"
|
|
|
+
|
|
|
+#: ../../guide.rst:438
|
|
|
+msgid ""
|
|
|
+"The output function (function name like ``put_xxx()``) will output the content "
|
|
|
+"to the \"current scope\" by default, and the \"current scope\" of the runtime "
|
|
|
+"context can be set by ``use_scope()``."
|
|
|
+msgstr ""
|
|
|
+"输出函数(函数名形如 ``put_xxx()`` )在默认情况下,会将内容输出到\"当前Scope\","
|
|
|
+"可以通过 ``use_scope()`` 设置运行时上下文的\"当前Scope\"。"
|
|
|
+
|
|
|
+#: ../../guide.rst:440
|
|
|
+msgid ""
|
|
|
+"In addition, you can use the ``scope`` parameter of the output function to "
|
|
|
+"specify the destination scope to output:"
|
|
|
+msgstr "此外,也可以通过输出函数的 ``scope`` 参数指定输出的目的Scope:"
|
|
|
+
|
|
|
+#: ../../guide.rst:442
|
|
|
+msgid ""
|
|
|
+"with use_scope('scope3'):\n"
|
|
|
+" put_text('text1 in scope3') # output to current scope: scope3\n"
|
|
|
+" put_text('text in ROOT scope', scope='ROOT') # output to ROOT Scope\n"
|
|
|
+"\n"
|
|
|
+"put_text('text2 in scope3', scope='scope3') # output to scope3"
|
|
|
+msgstr ""
|
|
|
+
|
|
|
+#: ../../guide.rst:454
|
|
|
+msgid ""
|
|
|
+"text1 in scope3\n"
|
|
|
+"text2 in scope3\n"
|
|
|
+"text in ROOT scope"
|
|
|
+msgstr ""
|
|
|
+
|
|
|
+#: ../../guide.rst:458
|
|
|
+msgid ""
|
|
|
+"In addition to directly specifying the target scope name, the ``scope`` "
|
|
|
+"parameter can also accept an integer to determine the scope by indexing the "
|
|
|
+"scope stack: 0 means the top level scope(the ROOT Scope), -1 means the current "
|
|
|
+"Scope, -2 means the scope used before entering the current scope, ..."
|
|
|
+msgstr ""
|
|
|
+"``scope`` 参数除了直接指定目标Scope名,还可以使用一个整形通过索引Scope栈来确定"
|
|
|
+"Scope:0表示最顶层也就是ROOT Scope,-1表示当前Scope,-2表示进入当前Scope前所使用"
|
|
|
+"的Scope,……"
|
|
|
+
|
|
|
+#: ../../guide.rst:460
|
|
|
+msgid ""
|
|
|
+"By default, the content output to the same scope will be arranged from top to "
|
|
|
+"bottom according to the calling order of the output function, and the output "
|
|
|
+"function called last will output the content to the bottom of the target scope. "
|
|
|
+"The output content can be inserted into other positions of the target scope by "
|
|
|
+"using the ``position`` parameter of the output function."
|
|
|
+msgstr ""
|
|
|
+"默认条件下,在同一Scope中的输出内容,会根据输出函数的调用顺序从上往下排列,最后"
|
|
|
+"调用的输出函数会输出内容到目标Scope的底部。通过输出函数的 ``position`` 参数可以"
|
|
|
+"将输出内容插入到目标Scope的其他位置。"
|
|
|
+
|
|
|
+#: ../../guide.rst:462
|
|
|
+msgid ""
|
|
|
+"Each output item in a scope has an index, the first item's index is 0, and the "
|
|
|
+"next item's index is incremented by one. You can also use a negative number to "
|
|
|
+"index the items in the scope, -1 means the last item, -2 means the item before "
|
|
|
+"the last..."
|
|
|
+msgstr ""
|
|
|
+"一个Scope中各次输出的元素具有像数组一样的索引,最前面的编号为0,以此往后递增加"
|
|
|
+"一;同样可以使用负数对Scope中的元素进行索引,-1表示最后面的元素,-2表示次后面的"
|
|
|
+"元素……"
|
|
|
+
|
|
|
+#: ../../guide.rst:464
|
|
|
+msgid ""
|
|
|
+"The ``position`` parameter of output functions is an integer. When "
|
|
|
+"``position>=0``, it means to insert content before the item whose index equal "
|
|
|
+"``position``; when ``position<0``, it means to insert content after the item "
|
|
|
+"whose index equal ``position``:"
|
|
|
+msgstr ""
|
|
|
+"``position`` 参数类型为整形, ``position>=0`` 时表示输出内容到目标Scope的第"
|
|
|
+"position号元素的前面; ``position<0`` 时表示输出内容到目标Scope第position号元素"
|
|
|
+"之后:"
|
|
|
+
|
|
|
+#: ../../guide.rst:466
|
|
|
+msgid ""
|
|
|
+"with use_scope('scope1'):\n"
|
|
|
+" put_text('A')\n"
|
|
|
+"## ----\n"
|
|
|
+"with use_scope('scope1'): # ..demo-only\n"
|
|
|
+" put_text('B', position=0) # insert B before A -> B A\n"
|
|
|
+"## ----\n"
|
|
|
+"with use_scope('scope1'): # ..demo-only\n"
|
|
|
+" put_text('C', position=-2) # insert C after B -> B C A\n"
|
|
|
+"## ----\n"
|
|
|
+"with use_scope('scope1'): # ..demo-only\n"
|
|
|
+" put_text('D', position=1) # insert D before C B -> B D C A"
|
|
|
+msgstr ""
|
|
|
+
|
|
|
+#: ../../guide.rst:482
|
|
|
+msgid "**Scope control**"
|
|
|
+msgstr "**输出域控制函数**"
|
|
|
+
|
|
|
+#: ../../guide.rst:484
|
|
|
+msgid ""
|
|
|
+"In addition to `use_scope() <pywebio.output.use_scope>`, PyWebIO also provides "
|
|
|
+"the following scope control functions:"
|
|
|
+msgstr "除了 `use_scope()` , PyWebIO同样提供了以下scope控制函数:"
|
|
|
+
|
|
|
+#: ../../guide.rst:486
|
|
|
+msgid ""
|
|
|
+"`set_scope(name) <pywebio.output.set_scope>` : Create scope at current "
|
|
|
+"location(or specified location)"
|
|
|
+msgstr ""
|
|
|
+"`set_scope(name) <pywebio.output.set_scope>` : 在当前位置(或指定位置)创建scope"
|
|
|
+
|
|
|
+#: ../../guide.rst:487
|
|
|
+msgid "`clear(scope) <pywebio.output.clear>` : Clear the contents of the scope"
|
|
|
+msgstr "`clear(scope) <pywebio.output.clear>` : 清除scope的内容"
|
|
|
+
|
|
|
+#: ../../guide.rst:488
|
|
|
+msgid "`remove(scope) <pywebio.output.remove>` : Remove scope"
|
|
|
+msgstr "`remove(scope) <pywebio.output.remove>` : 移除scope"
|
|
|
+
|
|
|
+#: ../../guide.rst:489
|
|
|
+msgid ""
|
|
|
+"`scroll_to(scope) <pywebio.output.scroll_to>` : Scroll the page to the scope"
|
|
|
+msgstr "`scroll_to(scope) <pywebio.output.scroll_to>` : 将页面滚动到scope处"
|
|
|
+
|
|
|
+#: ../../guide.rst:493
|
|
|
+msgid "Page environment settings"
|
|
|
+msgstr "页面环境设置"
|
|
|
+
|
|
|
+#: ../../guide.rst:495
|
|
|
+msgid "**Page Title**"
|
|
|
+msgstr "**页面标题**"
|
|
|
+
|
|
|
+#: ../../guide.rst:497
|
|
|
+msgid ""
|
|
|
+"You can call `set_env(title=...) <pywebio.session.set_env>` to set the page "
|
|
|
+"title。"
|
|
|
+msgstr "调用 `set_env(title=…) <pywebio.session.set_env>` 可以设置页面标题。"
|
|
|
+
|
|
|
+#: ../../guide.rst:499
|
|
|
+msgid "**Auto Scroll**"
|
|
|
+msgstr "**自动滚动**"
|
|
|
+
|
|
|
+#: ../../guide.rst:501
|
|
|
+msgid ""
|
|
|
+"When performing some continuous output (such as log output), you may want to "
|
|
|
+"scroll the page to the bottom automatically when there is new output. You can "
|
|
|
+"call `set_env(auto_scroll_bottom=True) <pywebio.session.set_env>` to enable "
|
|
|
+"automatic scrolling. Note that when enabled, only outputting to ROOT scope can "
|
|
|
+"trigger automatic scrolling."
|
|
|
+msgstr ""
|
|
|
+"在进行一些持续性的输出时(比如日志输出),有时希望在有新输出后自动将页面滚动到最下"
|
|
|
+"方,这时可以调用 `set_env(auto_scroll_bottom=True) <pywebio.session.set_env>` 来"
|
|
|
+"开启自动滚动。\n"
|
|
|
+"注意,开启后,只有输出到ROOT Scope才可以触发自动滚动。"
|
|
|
+
|
|
|
+#: ../../guide.rst:503
|
|
|
+msgid "**Output Animation**"
|
|
|
+msgstr "**输出动画**"
|
|
|
+
|
|
|
+#: ../../guide.rst:505
|
|
|
+msgid ""
|
|
|
+"By default, PyWebIO will use the fade-in animation effect to display the "
|
|
|
+"content. You can use `set_env(output_animation=False) <pywebio.session."
|
|
|
+"set_env>` to turn off the animation."
|
|
|
+msgstr ""
|
|
|
+"PyWebIO在输出内容时默认会使用淡入的动画效果来显示内容,可使用 "
|
|
|
+"`set_env(output_animation=False) <pywebio.session.set_env>` 来关闭动画。"
|
|
|
+
|
|
|
+#: ../../guide.rst:507
|
|
|
+msgid ""
|
|
|
+"To view the effects of environment settings, please visit :demo_host:`set_env "
|
|
|
+"Demo </?pywebio_api=set_env_demo>`"
|
|
|
+msgstr ""
|
|
|
+"有关不同环境配置的效果可查看 :demo_host:`set_env Demo </?"
|
|
|
+"pywebio_api=set_env_demo>`"
|
|
|
+
|
|
|
+#: ../../guide.rst:510
|
|
|
+msgid "Layout"
|
|
|
+msgstr "布局"
|
|
|
+
|
|
|
+#: ../../guide.rst:512
|
|
|
+msgid ""
|
|
|
+"In general, using the various output functions introduced above is enough to "
|
|
|
+"output what you want, but these outputs are arranged vertically. If you want to "
|
|
|
+"make a more complex layout (such as displaying a code block on the left side of "
|
|
|
+"the page and an image on the right), you need to use layout functions."
|
|
|
+msgstr ""
|
|
|
+"一般情况下,使用上文介绍的各种输出函数足以完成各种内容的展示,但直接调用输出函数"
|
|
|
+"产生的输出之间都是竖直排列的,如果想实现更复杂的布局(比如在页面左侧显示一个代码"
|
|
|
+"块,在右侧显示一个图像),就需要借助布局函数。"
|
|
|
+
|
|
|
+#: ../../guide.rst:514
|
|
|
+msgid ""
|
|
|
+"The ``pywebio.output`` module provides 3 layout functions, and you can create "
|
|
|
+"complex layouts by combining them:"
|
|
|
+msgstr ""
|
|
|
+"``pywebio.output`` 模块提供了3个布局函数,通过对他们进行组合可以完成各种复杂的布"
|
|
|
+"局:"
|
|
|
+
|
|
|
+#: ../../guide.rst:516
|
|
|
+msgid ""
|
|
|
+"`put_row() <pywebio.output.put_row>` : Use row layout to output content. The "
|
|
|
+"content is arranged horizontally"
|
|
|
+msgstr ""
|
|
|
+"`put_row() <pywebio.output.put_row>` : 使用行布局输出内容. 内容在水平方向上排列"
|
|
|
+
|
|
|
+#: ../../guide.rst:517
|
|
|
+msgid ""
|
|
|
+"`put_column() <pywebio.output.put_column>` : Use column layout to output "
|
|
|
+"content. The content is arranged vertically"
|
|
|
+msgstr ""
|
|
|
+"`put_column() <pywebio.output.put_column>` : 使用列布局输出内容. 内容在竖直方向"
|
|
|
+"上排列"
|
|
|
+
|
|
|
+#: ../../guide.rst:518
|
|
|
+msgid "`put_grid() <pywebio.output.put_grid>` : Output content using grid layout"
|
|
|
+msgstr "`put_grid() <pywebio.output.put_grid>` : 使用网格布局输出内容"
|
|
|
+
|
|
|
+#: ../../guide.rst:520
|
|
|
+msgid "Here is an example by combining ``put_row()`` and ``put_column()``:"
|
|
|
+msgstr "通过组合 ``put_row()`` 和 ``put_column()`` 可以实现灵活布局:"
|
|
|
+
|
|
|
+#: ../../guide.rst:522
|
|
|
+msgid ""
|
|
|
+"put_row([\n"
|
|
|
+" put_column([\n"
|
|
|
+" put_code('A'),\n"
|
|
|
+" put_row([\n"
|
|
|
+" put_code('B1'), None, # None represents the space between the "
|
|
|
+"output\n"
|
|
|
+" put_code('B2'), None,\n"
|
|
|
+" put_code('B3'),\n"
|
|
|
+" ]),\n"
|
|
|
+" put_code('C'),\n"
|
|
|
+" ]), None,\n"
|
|
|
+" put_code('D'), None,\n"
|
|
|
+" put_code('E')\n"
|
|
|
+"])"
|
|
|
+msgstr ""
|
|
|
+
|
|
|
+#: ../../guide.rst:545
|
|
|
+msgid "The layout function also supports customizing the size of each part::"
|
|
|
+msgstr "布局函数还支持自定义各部分的尺寸::"
|
|
|
+
|
|
|
+#: ../../guide.rst:547
|
|
|
+#, python-format
|
|
|
+msgid ""
|
|
|
+"put_row([put_image(...), put_image(...)], size='40% 60%') # The ratio of the "
|
|
|
+"width of two images is 2:3"
|
|
|
+msgstr ""
|
|
|
+"put_row([put_image(…), put_image(…)], size='40% 60%') # 左右两图宽度比2:3"
|
|
|
+
|
|
|
+#: ../../guide.rst:549
|
|
|
+msgid ""
|
|
|
+"For more information, please refer to the :ref:`layout function documentation "
|
|
|
+"<style_and_layout>`."
|
|
|
+msgstr ""
|
|
|
+"更多布局函数的用法及代码示例请查阅 :ref:`布局函数文档 <style_and_layout>` ."
|
|
|
+
|
|
|
+#: ../../guide.rst:552
|
|
|
+msgid "Style"
|
|
|
+msgstr "样式"
|
|
|
+
|
|
|
+#: ../../guide.rst:554
|
|
|
+msgid ""
|
|
|
+"If you are familiar with `CSS <https://en.wikipedia.org/wiki/CSS>`_ styles, you "
|
|
|
+"can use the `style() <pywebio.output.style>` function to set a custom style for "
|
|
|
+"the output."
|
|
|
+msgstr ""
|
|
|
+"如果你熟悉 `CSS样式 <https://www.google.com/search?q=CSS%E6%A0%B7%E5%BC%8F>`_ ,"
|
|
|
+"你还可以使用 `style() <pywebio.output.style>` 函数给输出设定自定义样式。"
|
|
|
+
|
|
|
+#: ../../guide.rst:556
|
|
|
+msgid "You can set the CSS style for a single ``put_xxx()`` output:"
|
|
|
+msgstr "可以给单个的 ``put_xxx()`` 输出设定CSS样式,也可以配合组合输出使用:"
|
|
|
+
|
|
|
+#: ../../guide.rst:558
|
|
|
+msgid ""
|
|
|
+"style(put_text('Red'), 'color: red')\n"
|
|
|
+"\n"
|
|
|
+"## ----\n"
|
|
|
+"put_table([\n"
|
|
|
+" ['A', 'B'],\n"
|
|
|
+" ['C', style(put_text('Red'), 'color: red')],\n"
|
|
|
+"])"
|
|
|
+msgstr ""
|
|
|
+
|
|
|
+#: ../../guide.rst:570
|
|
|
+msgid ""
|
|
|
+"`style() <pywebio.output.style>` also accepts a list of output calls, `style() "
|
|
|
+"<pywebio.output.style>` will set the CSS style for each item of the list:"
|
|
|
+msgstr ""
|
|
|
+"``style()`` 也接受列表作为输入,``style()`` 会为列表的每一项都设置CSS样式,返回"
|
|
|
+"值可以直接输出,可用于任何接受 ``put_xxx()`` 列表的地方:"
|
|
|
+
|
|
|
+#: ../../guide.rst:572
|
|
|
+msgid ""
|
|
|
+"style([\n"
|
|
|
+" put_text('Red'),\n"
|
|
|
+" put_markdown('~~del~~')\n"
|
|
|
+"], 'color: red')\n"
|
|
|
+"\n"
|
|
|
+"## ----\n"
|
|
|
+"put_collapse('title', style([\n"
|
|
|
+" put_text('text'),\n"
|
|
|
+" put_markdown('~~del~~'),\n"
|
|
|
+"], 'margin-left: 20px'))"
|
|
|
+msgstr ""
|
|
|
+
|
|
|
+#: ../../guide.rst:591
|
|
|
+msgid "Server mode and Script mode"
|
|
|
+msgstr "Server模式与Script模式"
|
|
|
+
|
|
|
+#: ../../guide.rst:593
|
|
|
+msgid ""
|
|
|
+"In the :ref:`Hello, world <hello_word>` section, we already know that PyWebIO "
|
|
|
+"supports two modes: running as a script and using `start_server() <pywebio."
|
|
|
+"platform.tornado.start_server>` to run as a web service."
|
|
|
+msgstr ""
|
|
|
+"在 :ref:`Hello, world <hello_word>` 一节中,已经知道,PyWebIO支持在普通的脚本中"
|
|
|
+"调用和使用 `start_server() <pywebio.platform.tornado.start_server>` 启动一个Web"
|
|
|
+"服务两种模式。"
|
|
|
+
|
|
|
+#: ../../guide.rst:595 ../../guide.rst:648
|
|
|
+msgid "**Server mode**"
|
|
|
+msgstr "**Server模式**"
|
|
|
+
|
|
|
+#: ../../guide.rst:597
|
|
|
+msgid ""
|
|
|
+"In Server mode, PyWebIO will start a web server to continuously provide "
|
|
|
+"services. A task function needs to be provided. When the user accesses the "
|
|
|
+"service address, PyWebIO will open a new session and run the task function."
|
|
|
+msgstr ""
|
|
|
+"在Server模式下,PyWebIO会启动一个Web服务来持续性地提供服务。需要提供一个任务函数"
|
|
|
+"(类似于Web开发中的视图函数),当用户访问服务地址时,PyWebIO会开启一个新会话并运行"
|
|
|
+"任务函数。"
|
|
|
+
|
|
|
+#: ../../guide.rst:599
|
|
|
+msgid ""
|
|
|
+"Use `start_server() <pywebio.platform.tornado.start_server>` to start a web "
|
|
|
+"service. In addition to accepting a function as task function, "
|
|
|
+"``start_server()`` also accepts a list of task function or a dictionary of it, "
|
|
|
+"so that one PyWebIO Server can have multiple services with different functions. "
|
|
|
+"You can use `go_app() <pywebio.session.go_app>` or `put_link() <pywebio.output."
|
|
|
+"put_link>` to jump between services::"
|
|
|
+msgstr ""
|
|
|
+"使用 `start_server() <pywebio.platform.tornado.start_server>` 来启动PyWebIO的"
|
|
|
+"Server模式, `start_server() <pywebio.platform.tornado.start_server>` 除了接收一"
|
|
|
+"个函数作为任务函数外,\n"
|
|
|
+"还支持传入函数列表或字典,从而使一个PyWebIO Server下可以有多个不同功能的服务,服"
|
|
|
+"务之间可以通过 `go_app() <pywebio.session.go_app>` 或 `put_link() <pywebio."
|
|
|
+"output.put_link>` 进行跳转::"
|
|
|
+
|
|
|
+#: ../../guide.rst:601
|
|
|
+msgid ""
|
|
|
+"def task_1():\n"
|
|
|
+" put_text('task_1')\n"
|
|
|
+" put_buttons(['Go task 2'], [lambda: go_app('task_2')])\n"
|
|
|
+" hold()\n"
|
|
|
+"\n"
|
|
|
+"def task_2():\n"
|
|
|
+" put_text('task_2')\n"
|
|
|
+" put_buttons(['Go task 1'], [lambda: go_app('task_1')])\n"
|
|
|
+" hold()\n"
|
|
|
+"\n"
|
|
|
+"def index():\n"
|
|
|
+" put_link('Go task 1', app='task_1') # Use `app` parameter to specify the "
|
|
|
+"task name\n"
|
|
|
+" put_link('Go task 2', app='task_2')\n"
|
|
|
+"\n"
|
|
|
+"start_server([index, task_1, task_2]) # or start_server({'index': index, "
|
|
|
+"'task_1': task_1, 'task_2': task_2}) For more information, please refer to the "
|
|
|
+"function documentation."
|
|
|
+msgstr ""
|
|
|
+"def task_1():\n"
|
|
|
+" put_text('task_1')\n"
|
|
|
+" put_buttons(['Go task 2'], [lambda: go_app('task_2')])\n"
|
|
|
+" hold()\n"
|
|
|
+"\n"
|
|
|
+"def task_2():\n"
|
|
|
+" put_text('task_2')\n"
|
|
|
+" put_buttons(['Go task 1'], [lambda: go_app('task_1')])\n"
|
|
|
+" hold()\n"
|
|
|
+"\n"
|
|
|
+"def index():\n"
|
|
|
+" put_link('Go task 1', app='task_1') # 使用app参数指定任务名\n"
|
|
|
+" put_link('Go task 2', app='task_2')\n"
|
|
|
+"\n"
|
|
|
+"start_server([index, task_1, task_2]) # 或 start_server({'index': index, "
|
|
|
+"'task_1': task_1, 'task_2': task_2}) For more information, please refer to the "
|
|
|
+"function documentation."
|
|
|
+
|
|
|
+#: ../../guide.rst:618
|
|
|
+msgid ""
|
|
|
+"You can use `pywebio.platform.seo()` to set the `SEO <https://en.wikipedia.org/"
|
|
|
+"wiki/Search_engine_optimization>`_ information. If not ``seo()`` is not used, "
|
|
|
+"the `docstring <https://www.python.org/dev/peps/pep-0257/>`_ of the task "
|
|
|
+"function will be regarded as SEO information by default."
|
|
|
+msgstr ""
|
|
|
+"可以使用 `pywebio.platform.seo()` 函数来设置任务函数SEO信息(在被搜索引擎索引时"
|
|
|
+"提供的网页信息,包含应用标题和应用简介),如果不使用 ``seo()`` 函数,默认条件"
|
|
|
+"下,PyWebIO会将任务函数的函数注释作为SEO信息(应用标题和简介之间使用一个空行分"
|
|
|
+"隔)。"
|
|
|
+
|
|
|
+#: ../../guide.rst:622
|
|
|
+msgid ""
|
|
|
+"Note that in Server mode, PyWebIO's input and output functions can only be "
|
|
|
+"called in the context of task functions. For example, the following code is "
|
|
|
+"**not allowed**::"
|
|
|
+msgstr ""
|
|
|
+"注意,在Server模式下,仅能在任务函数上下文中对PyWebIO的交互函数进行调用。比如如"
|
|
|
+"下调用是 **不被允许的** ::"
|
|
|
+
|
|
|
+#: ../../guide.rst:624
|
|
|
+msgid ""
|
|
|
+"import pywebio\n"
|
|
|
+"from pywebio.input import input\n"
|
|
|
+"\n"
|
|
|
+"port = input('Input port number:') # ❌ error\n"
|
|
|
+"pywebio.start_server(my_task_func, port=int(port))"
|
|
|
+msgstr ""
|
|
|
+
|
|
|
+#: ../../guide.rst:631 ../../guide.rst:644
|
|
|
+msgid "**Script mode**"
|
|
|
+msgstr "**Script模式**"
|
|
|
+
|
|
|
+#: ../../guide.rst:633
|
|
|
+msgid "In Script mode, PyWebIO input and output functions can be called anywhere."
|
|
|
+msgstr "Script模式下,在任何位置都可以调用PyWebIO的交互函数。"
|
|
|
+
|
|
|
+#: ../../guide.rst:635
|
|
|
+msgid ""
|
|
|
+"If the user closes the browser before the end of the session, then calls to "
|
|
|
+"PyWebIO input and output functions in the session will cause a "
|
|
|
+"`SessionException <pywebio.exceptions.SessionException>` exception."
|
|
|
+msgstr ""
|
|
|
+"如果用户在会话结束之前关闭了浏览器,那么之后会话内对于PyWebIO交互函数的调用将会"
|
|
|
+"引发一个 `SessionException <pywebio.exceptions.SessionException>` 异常。"
|
|
|
+
|
|
|
+#: ../../guide.rst:640
|
|
|
+msgid "Concurrent"
|
|
|
+msgstr "并发"
|
|
|
+
|
|
|
+#: ../../guide.rst:642
|
|
|
+msgid "PyWebIO can be used in a multi-threading environment."
|
|
|
+msgstr "PyWebIO 支持在多线程环境中使用。"
|
|
|
+
|
|
|
+#: ../../guide.rst:646
|
|
|
+msgid ""
|
|
|
+"In Script mode, you can freely start new thread and call PyWebIO interactive "
|
|
|
+"functions in it. When all `non-daemonic <https://docs.python.org/3/library/"
|
|
|
+"threading.html#thread-objects>`_ threads finish running, the script exits."
|
|
|
+msgstr ""
|
|
|
+"在 Script模式下,你可以自由地启动线程,并在其中调用PyWebIO的交互函数。当所有非 "
|
|
|
+"`Daemon线程 <https://docs.python.org/3/library/threading.html#thread-objects>`_ "
|
|
|
+"运行结束后,脚本退出。"
|
|
|
+
|
|
|
+#: ../../guide.rst:650
|
|
|
+msgid ""
|
|
|
+"In Server mode, if you need to use PyWebIO interactive functions in new thread, "
|
|
|
+"you need to use `register_thread(thread) <pywebio.session.register_thread>` to "
|
|
|
+"register the new thread (so that PyWebIO can know which session the thread "
|
|
|
+"belongs to). If the PyWebIO interactive function is not used in the new thread, "
|
|
|
+"no registration is required. Threads that are not registered with "
|
|
|
+"`register_thread(thread) <pywebio.session.register_thread>` calling PyWebIO's "
|
|
|
+"interactive functions will cause `SessionNotFoundException <pywebio.exceptions."
|
|
|
+"SessionNotFoundException>`. When both the task function of the session and the "
|
|
|
+"thread registered through `register_thread(thread) <pywebio.session."
|
|
|
+"register_thread>` in the session have finished running, the session is closed."
|
|
|
+msgstr ""
|
|
|
+"Server模式下,如果需要在新创建的线程中使用PyWebIO的交互函数,需要手动调用 "
|
|
|
+"`register_thread(thread) <pywebio.session.register_thread>` 对新进程进行注册(这"
|
|
|
+"样PyWebIO才能知道新创建的线程属于哪个会话)。\n"
|
|
|
+"如果新创建的线程中没有使用到PyWebIO的交互函数,则无需注册。没有使用 "
|
|
|
+"`register_thread(thread) <pywebio.session.register_thread>` 注册的线程不受会话管"
|
|
|
+"理,其调用PyWebIO的交互函数将会产生 `SessionNotFoundException <pywebio."
|
|
|
+"exceptions.SessionNotFoundException>` 异常。\n"
|
|
|
+"当会话的任务函数和会话内通过 `register_thread(thread) <pywebio.session."
|
|
|
+"register_thread>` 注册的线程都结束运行时,会话关闭。"
|
|
|
+
|
|
|
+#: ../../guide.rst:652
|
|
|
+msgid "Example of using multi-threading in Server mode::"
|
|
|
+msgstr "Server模式下多线程的使用示例::"
|
|
|
+
|
|
|
+#: ../../guide.rst:654
|
|
|
+msgid ""
|
|
|
+"def show_time():\n"
|
|
|
+" while True:\n"
|
|
|
+" with use_scope(name='time', clear=True):\n"
|
|
|
+" put_text(datetime.datetime.now())\n"
|
|
|
+" time.sleep(1)\n"
|
|
|
+"\n"
|
|
|
+"def app():\n"
|
|
|
+" t = threading.Thread(target=show_time)\n"
|
|
|
+" register_thread(t)\n"
|
|
|
+" put_markdown('## Clock')\n"
|
|
|
+" t.start() # run `show_time()` in background\n"
|
|
|
+"\n"
|
|
|
+" # ❌ this thread will cause `SessionNotFoundException`\n"
|
|
|
+" threading.Thread(target=show_time).start()\n"
|
|
|
+"\n"
|
|
|
+" put_text('Background task started.')\n"
|
|
|
+"\n"
|
|
|
+"\n"
|
|
|
+"start_server(app, port=8080, debug=True)"
|
|
|
+msgstr ""
|
|
|
+
|
|
|
+#: ../../guide.rst:678 ../../guide.rst:898
|
|
|
+msgid "Close of session"
|
|
|
+msgstr "会话的结束"
|
|
|
+
|
|
|
+#: ../../guide.rst:680
|
|
|
+msgid ""
|
|
|
+"The close of session may also be caused by the user closing the browser page. "
|
|
|
+"After the browser page is closed, PyWebIO input function calls that have not "
|
|
|
+"yet returned in the current session will cause `SessionClosedException <pywebio."
|
|
|
+"exceptions.SessionClosedException>`, and subsequent calls to PyWebIO "
|
|
|
+"interactive functions will cause `SessionNotFoundException <pywebio.exceptions."
|
|
|
+"SessionNotFoundException>` or `SessionClosedException <pywebio.exceptions."
|
|
|
+"SessionClosedException>`."
|
|
|
+msgstr ""
|
|
|
+"会话还会因为用户的关闭浏览器而结束,这时当前会话内还未返回的PyWebIO输入函数调用"
|
|
|
+"将抛出 `SessionClosedException <pywebio.exceptions.SessionClosedException>` 异"
|
|
|
+"常,之后对于PyWebIO交互函数的调用将会产生 `SessionNotFoundException <pywebio."
|
|
|
+"exceptions.SessionNotFoundException>` 或 `SessionClosedException <pywebio."
|
|
|
+"exceptions.SessionClosedException>` 异常。"
|
|
|
+
|
|
|
+#: ../../guide.rst:682
|
|
|
+msgid ""
|
|
|
+"You can use `defer_call(func) <pywebio.session.defer_call>` to set the function "
|
|
|
+"to be called when the session closes. Whether it is because the user closes the "
|
|
|
+"page or the task finishes to cause session closed, the function set by "
|
|
|
+"`defer_call(func) <pywebio.session.defer_call>` will be executed. "
|
|
|
+"`defer_call(func) <pywebio.session.defer_call>` can be used for resource "
|
|
|
+"cleaning. You can call `defer_call(func) <pywebio.session.defer_call>` multiple "
|
|
|
+"times in the session, and the set functions will be executed sequentially after "
|
|
|
+"the session closes."
|
|
|
+msgstr ""
|
|
|
+"可以使用 `defer_call(func) <pywebio.session.defer_call>` 来设置会话结束时需要调"
|
|
|
+"用的函数。无论是因为用户主动关闭页面还是任务结束使得会话关闭,设置的函数都会被执"
|
|
|
+"行。\n"
|
|
|
+"`defer_call(func) <pywebio.session.defer_call>` 可以用于资源清理等工作。在会话中"
|
|
|
+"可以多次调用 `defer_call() <pywebio.session.defer_call>` ,会话结束后将会顺序执行"
|
|
|
+"设置的函数。"
|
|
|
+
|
|
|
+#: ../../guide.rst:687
|
|
|
+msgid "Integration with web framework"
|
|
|
+msgstr "与Web框架集成"
|
|
|
+
|
|
|
+#: ../../guide.rst:689
|
|
|
+msgid ""
|
|
|
+"The PyWebIO application can be integrated into an existing Python Web project, "
|
|
|
+"and the PyWebIO application and the Web project share a web framework. PyWebIO "
|
|
|
+"currently supports integration with Flask, Tornado, Django and aiohttp web "
|
|
|
+"frameworks."
|
|
|
+msgstr ""
|
|
|
+"可以将PyWebIO应用集成到现有的Python Web项目中,PyWebIO应用与Web项目共用一个Web框"
|
|
|
+"架。目前支持与Flask、Tornado、Django和aiohttp Web框架的集成。"
|
|
|
+
|
|
|
+#: ../../guide.rst:691
|
|
|
+msgid "The integration methods of different web frameworks are as follows:"
|
|
|
+msgstr "不同Web框架的集成方法如下:"
|
|
|
+
|
|
|
+#: ../../guide.rst:695
|
|
|
+msgid "Tornado"
|
|
|
+msgstr ""
|
|
|
+
|
|
|
+#: ../../guide.rst:697
|
|
|
+msgid "Need to add a ``RequestHandler`` to Tornado application::"
|
|
|
+msgstr "需要在Tornado应用中引入一个 ``RequestHandler`` ::"
|
|
|
+
|
|
|
+#: ../../guide.rst:699
|
|
|
+msgid ""
|
|
|
+"import tornado.ioloop\n"
|
|
|
+"import tornado.web\n"
|
|
|
+"from pywebio.platform.tornado import webio_handler\n"
|
|
|
+"from pywebio import STATIC_PATH\n"
|
|
|
+"\n"
|
|
|
+"class MainHandler(tornado.web.RequestHandler):\n"
|
|
|
+" def get(self):\n"
|
|
|
+" self.write(\"Hello, world\")\n"
|
|
|
+"\n"
|
|
|
+"if __name__ == \"__main__\":\n"
|
|
|
+" application = tornado.web.Application([\n"
|
|
|
+" (r\"/\", MainHandler),\n"
|
|
|
+" (r\"/tool\", webio_handler(task_func)), # `task_func` is PyWebIO task "
|
|
|
+"function\n"
|
|
|
+" ])\n"
|
|
|
+" application.listen(port=80, address='localhost')\n"
|
|
|
+" tornado.ioloop.IOLoop.current().start()"
|
|
|
+msgstr ""
|
|
|
+
|
|
|
+#: ../../guide.rst:717
|
|
|
+msgid ""
|
|
|
+"In above code, we use `webio_handler(task_func) <pywebio.platform.tornado."
|
|
|
+"webio_handler>` to get the Tornado `WebSocketHandler <https://www.tornadoweb."
|
|
|
+"org/en/stable/websocket.html#tornado.websocket.WebSocketHandler>`_ that "
|
|
|
+"communicates with the browser, and bind it to the ``/tool`` path. After "
|
|
|
+"starting the Tornado server, you can visit ``http://localhost/tool`` to open "
|
|
|
+"the PyWebIO application."
|
|
|
+msgstr ""
|
|
|
+"以上代码调用 `webio_handler(task_func) <pywebio.platform.tornado."
|
|
|
+"webio_handler>` 来获得PyWebIO和浏览器进行通讯的Tornado `WebSocketHandler "
|
|
|
+"<https://www.tornadoweb.org/en/stable/websocket.html#tornado.websocket."
|
|
|
+"WebSocketHandler>`_ ,并将其绑定在 ``/tool`` 路由下。启动Tornado服务器后,访问 "
|
|
|
+"``http://localhost/tool`` 即可打开PyWebIO应用。"
|
|
|
+
|
|
|
+#: ../../guide.rst:721
|
|
|
+msgid ""
|
|
|
+"PyWebIO uses the WebSocket protocol to communicate with the browser in Tornado. "
|
|
|
+"If your Tornado application is behind a reverse proxy (such as Nginx), you may "
|
|
|
+"need to configure the reverse proxy to support the WebSocket protocol. :ref:"
|
|
|
+"`Here <nginx_ws_config>` is an example of Nginx WebSocket configuration."
|
|
|
+msgstr ""
|
|
|
+"当使用Tornado后端时,PyWebIO使用WebSocket协议和浏览器进行通讯,如果你的Tornado应"
|
|
|
+"用处在反向代理(比如Nginx)之后,可能需要特别配置反向代理来支持WebSocket协议,:"
|
|
|
+"ref:`这里 <nginx_ws_config>` 有一个Nginx配置WebSocket的例子。"
|
|
|
+
|
|
|
+#: ../../guide.rst:723
|
|
|
+msgid "Flask"
|
|
|
+msgstr ""
|
|
|
+
|
|
|
+#: ../../guide.rst:725
|
|
|
+msgid "One route need to be added to communicate with the browser through HTTP::"
|
|
|
+msgstr "需要添加一个PyWebIO相关的路由,用来和浏览器进行Http通讯::"
|
|
|
+
|
|
|
+#: ../../guide.rst:727
|
|
|
+msgid ""
|
|
|
+"from pywebio.platform.flask import webio_view\n"
|
|
|
+"from pywebio import STATIC_PATH\n"
|
|
|
+"from flask import Flask, send_from_directory\n"
|
|
|
+"\n"
|
|
|
+"app = Flask(__name__)\n"
|
|
|
+"\n"
|
|
|
+"# `task_func` is PyWebIO task function\n"
|
|
|
+"app.add_url_rule('/tool', 'webio_view', webio_view(task_func),\n"
|
|
|
+" methods=['GET', 'POST', 'OPTIONS']) # need GET,POST and OPTIONS "
|
|
|
+"methods\n"
|
|
|
+"\n"
|
|
|
+"app.run(host='localhost', port=80)"
|
|
|
+msgstr ""
|
|
|
+
|
|
|
+#: ../../guide.rst:740
|
|
|
+msgid ""
|
|
|
+"In above code, we use `webio_view(task_func) <pywebio.platform.flask."
|
|
|
+"webio_view>` to get the Flask view of the PyWebIO application, and bind it to "
|
|
|
+"``/tool`` path. After starting the Flask application, visit ``http://localhost/"
|
|
|
+"tool`` to open the PyWebIO application."
|
|
|
+msgstr ""
|
|
|
+"以上代码使用 `webio_view(task_func) <pywebio.platform.flask.webio_view>` 来获得"
|
|
|
+"运行PyWebIO应用的Flask视图 ,并调用 `Flask.add_url_rule <https://flask."
|
|
|
+"palletsprojects.com/en/1.1.x/api/#flask.Flask.add_url_rule>`_ 将其绑定在 ``/"
|
|
|
+"tool`` 路径下。启动Flask应用后,访问 ``http://localhost/tool`` 即可打开PyWebIO应"
|
|
|
+"用。"
|
|
|
+
|
|
|
+#: ../../guide.rst:742
|
|
|
+msgid "Django"
|
|
|
+msgstr ""
|
|
|
+
|
|
|
+#: ../../guide.rst:744
|
|
|
+msgid "Need to add a route in ``urls.py``::"
|
|
|
+msgstr "在django的路由配置文件 ``urls.py`` 中加入PyWebIO相关的路由即可::"
|
|
|
+
|
|
|
+#: ../../guide.rst:746
|
|
|
+msgid ""
|
|
|
+"# urls.py\n"
|
|
|
+"\n"
|
|
|
+"from functools import partial\n"
|
|
|
+"from django.urls import path\n"
|
|
|
+"from django.views.static import serve\n"
|
|
|
+"from pywebio import STATIC_PATH\n"
|
|
|
+"from pywebio.platform.django import webio_view\n"
|
|
|
+"\n"
|
|
|
+"# `task_func` is PyWebIO task function\n"
|
|
|
+"webio_view_func = webio_view(task_func)\n"
|
|
|
+"\n"
|
|
|
+"urlpatterns = [\n"
|
|
|
+" path(r\"tool\", webio_view_func),\n"
|
|
|
+"]"
|
|
|
+msgstr ""
|
|
|
+
|
|
|
+#: ../../guide.rst:762
|
|
|
+msgid ""
|
|
|
+"In above code, we add a routing rule to bind the view function of the PyWebIO "
|
|
|
+"application to the ``/tool`` path After starting the Django server, visit "
|
|
|
+"``http://localhost/tool`` to open the PyWebIO application"
|
|
|
+msgstr ""
|
|
|
+"以上代码使用添加了一条路由规则将PyWebIO应用的视图函数绑定到 ``/tool`` 路径下。\n"
|
|
|
+"启动Django应用后,访问 ``http://localhost/tool`` 即可打开PyWebIO应用"
|
|
|
+
|
|
|
+#: ../../guide.rst:765
|
|
|
+msgid "aiohttp"
|
|
|
+msgstr ""
|
|
|
+
|
|
|
+#: ../../guide.rst:767
|
|
|
+msgid ""
|
|
|
+"One route need to be added to communicate with the browser through WebSocket:::"
|
|
|
+msgstr "需要添加一个PyWebIO相关的路由,用来和浏览器进行WebSocket通讯::"
|
|
|
+
|
|
|
+#: ../../guide.rst:769
|
|
|
+msgid ""
|
|
|
+"from aiohttp import web\n"
|
|
|
+"from pywebio.platform.aiohttp import static_routes, webio_handler\n"
|
|
|
+"\n"
|
|
|
+"app = web.Application()\n"
|
|
|
+"# `task_func` is PyWebIO task function\n"
|
|
|
+"app.add_routes([web.get('/tool', webio_handler(task_func))])\n"
|
|
|
+"\n"
|
|
|
+"web.run_app(app, host='localhost', port=80)"
|
|
|
+msgstr ""
|
|
|
+
|
|
|
+#: ../../guide.rst:778
|
|
|
+msgid ""
|
|
|
+"After starting the aiohttp server, visit ``http://localhost/tool`` to open the "
|
|
|
+"PyWebIO application"
|
|
|
+msgstr "启动aiohttp应用后,访问 ``http://localhost/tool`` 即可打开PyWebIO应用"
|
|
|
+
|
|
|
+#: ../../guide.rst:782
|
|
|
+msgid ""
|
|
|
+"PyWebIO uses the WebSocket protocol to communicate with the browser in aiohttp. "
|
|
|
+"If your aiohttp server is behind a reverse proxy (such as Nginx), you may need "
|
|
|
+"to configure the reverse proxy to support the WebSocket protocol. :ref:`Here "
|
|
|
+"<nginx_ws_config>` is an example of Nginx WebSocket configuration."
|
|
|
+msgstr ""
|
|
|
+"当使用aiohttp后端时,PyWebIO使用WebSocket协议和浏览器进行通讯,如果你的aiohttp应"
|
|
|
+"用处在反向代理(比如Nginx)之后,\n"
|
|
|
+"可能需要特别配置反向代理来支持WebSocket协议,:ref:`这里 <nginx_ws_config>` 有一"
|
|
|
+"个Nginx配置WebSocket的例子。"
|
|
|
+
|
|
|
+#: ../../guide.rst:787
|
|
|
+msgid "Notes"
|
|
|
+msgstr ""
|
|
|
+
|
|
|
+#: ../../guide.rst:788
|
|
|
+msgid "**Static resources Hosting**"
|
|
|
+msgstr "**PyWebIO静态资源的托管**"
|
|
|
+
|
|
|
+#: ../../guide.rst:790
|
|
|
+msgid ""
|
|
|
+"By default, the front-end of PyWebIO gets required static resources from CDN. "
|
|
|
+"If you want to deploy PyWebIO applications in an offline environment, you need "
|
|
|
+"to host static files by yourself, and set the ``cdn`` parameter of "
|
|
|
+"``webio_view()`` or ``webio_handler()`` to ``False``."
|
|
|
+msgstr ""
|
|
|
+"PyWebIO默认使用CDN来获取前端的静态资源,如果要将PyWebIO应用部署到离线环境中,需"
|
|
|
+"要自行托管静态文件,\n"
|
|
|
+"并将 ``webio_view()`` 或 ``webio_handler()`` 的 ``cdn`` 参数设置为 ``False`` 。"
|
|
|
+
|
|
|
+#: ../../guide.rst:792
|
|
|
+msgid ""
|
|
|
+"When setting ``cdn=False`` , you need to host the static resources in the same "
|
|
|
+"directory as the PyWebIO application. In addition, you can also pass a string "
|
|
|
+"to ``cdn`` parameter to directly set the deployment directory of PyWebIO static "
|
|
|
+"resources."
|
|
|
+msgstr ""
|
|
|
+"``cdn=False`` 时需要将静态资源托管在和PyWebIO应用同级的目录下。\n"
|
|
|
+"同时,也可以通过 ``cdn`` 参数直接设置PyWebIO静态资源的部署目录。"
|
|
|
+
|
|
|
+#: ../../guide.rst:795
|
|
|
+msgid ""
|
|
|
+"The path of the static file of PyWebIO is stored in ``pywebio.STATIC_PATH``, "
|
|
|
+"you can use the command ``python3 -c \"import pywebio; print(pywebio."
|
|
|
+"STATIC_PATH)\"`` to print it out."
|
|
|
+msgstr ""
|
|
|
+"PyWebIO的静态文件的路径可保存在 ``pywebio.STATIC_PATH`` 中,可使用命令 "
|
|
|
+"``python3 -c \"import pywebio; print(pywebio.STATIC_PATH)\"`` 将其打印出来。"
|
|
|
+
|
|
|
+#: ../../guide.rst:797
|
|
|
+msgid ""
|
|
|
+"``start_server()`` also support ``cdn`` parameter, if it is set to ``False``, "
|
|
|
+"the static resource will be hosted in local server automatically, without "
|
|
|
+"manual hosting."
|
|
|
+msgstr ""
|
|
|
+"使用 ``start_server()`` 启动的应用,如果将 ``cdn`` 参数设置为 ``False`` ,会自动"
|
|
|
+"启动一个本地的静态资源托管服务,无需手动托管。"
|
|
|
+
|
|
|
+#: ../../guide.rst:803
|
|
|
+msgid "Coroutine-based session"
|
|
|
+msgstr "基于协程的会话"
|
|
|
+
|
|
|
+#: ../../guide.rst:805
|
|
|
+msgid ""
|
|
|
+"This section will introduce the advanced features of PyWebIO --- coroutine-"
|
|
|
+"based session. In most cases, you don’t need it. All functions or methods in "
|
|
|
+"PyWebIO that are only used for coroutine sessions are specifically noted in the "
|
|
|
+"document."
|
|
|
+msgstr ""
|
|
|
+"关于协程内容属于高级特性,您不必使用此部分也可以实现PyWebIO支持的全部功能。"
|
|
|
+"PyWebIO中所有仅用于协程会话的函数或方法都在文档中有特别说明。"
|
|
|
+
|
|
|
+#: ../../guide.rst:807
|
|
|
+msgid ""
|
|
|
+"PyWebIO's session is based on thread by default. Each time a user opens a "
|
|
|
+"session connection to the server, PyWebIO will start a thread to run the task "
|
|
|
+"function. In addition to thread-based sessions, PyWebIO also provides coroutine-"
|
|
|
+"based sessions. Coroutine-based sessions accept coroutine functions as task "
|
|
|
+"functions."
|
|
|
+msgstr ""
|
|
|
+"PyWebIO的会话实现默认是基于线程的,用户每打开一个和服务端的会话连接,PyWebIO会启"
|
|
|
+"动一个线程来运行任务函数。\n"
|
|
|
+"除了基于线程的会话,PyWebIO还提供了基于协程的会话。基于协程的会话接受协程函数作"
|
|
|
+"为任务函数。"
|
|
|
+
|
|
|
+#: ../../guide.rst:809
|
|
|
+msgid ""
|
|
|
+"The session based on the coroutine is a single-thread model, which means that "
|
|
|
+"all sessions run in a single thread. For IO-bound tasks, coroutines take up "
|
|
|
+"fewer resources than threads and have performance comparable to threads. In "
|
|
|
+"addition, the context switching of the coroutine is predictable, which can "
|
|
|
+"reduce the need for program synchronization and locking, and can effectively "
|
|
|
+"avoid most critical section problems."
|
|
|
+msgstr ""
|
|
|
+"基于协程的会话为单线程模型,所有会话都运行在一个线程内。对于IO密集型的任务,协程"
|
|
|
+"比线程占用更少的资源同时又拥有媲美于线程的性能。\n"
|
|
|
+"另外,协程的上下文切换具有可预测性,能够减少程序同步与加锁的需要,可以有效避免大"
|
|
|
+"多数临界区问题。"
|
|
|
+
|
|
|
+#: ../../guide.rst:812
|
|
|
+msgid "Using coroutine session"
|
|
|
+msgstr "使用协程会话"
|
|
|
+
|
|
|
+#: ../../guide.rst:814
|
|
|
+msgid ""
|
|
|
+"To use coroutine-based session, you need to use the ``async`` keyword to "
|
|
|
+"declare the task function as a coroutine function, and use the ``await`` syntax "
|
|
|
+"to call the PyWebIO input function:"
|
|
|
+msgstr ""
|
|
|
+"要使用基于协程的会话,需要使用 ``async`` 关键字将任务函数声明为协程函数,并使用 "
|
|
|
+"``await`` 语法调用PyWebIO输入函数:"
|
|
|
+
|
|
|
+#: ../../guide.rst:816
|
|
|
+#, python-format
|
|
|
+msgid ""
|
|
|
+" from pywebio.input import *\n"
|
|
|
+" from pywebio.output import *\n"
|
|
|
+" from pywebio import start_server\n"
|
|
|
+"\n"
|
|
|
+" async def say_hello():\n"
|
|
|
+" name = await input(\"what's your name?\")\n"
|
|
|
+" put_text('Hello, %s' % name)\n"
|
|
|
+"\n"
|
|
|
+" start_server(say_hello, auto_open_webbrowser=True)"
|
|
|
+msgstr ""
|
|
|
+
|
|
|
+#: ../../guide.rst:830
|
|
|
+msgid ""
|
|
|
+"In the coroutine task function, you can also use ``await`` to call other "
|
|
|
+"coroutines or ( `awaitable objects <https://docs.python.org/3/library/asyncio-"
|
|
|
+"task.html#asyncio-awaitables>`_ ) in the standard library `asyncio <https://"
|
|
|
+"docs.python.org/3/library/asyncio.html>`_:"
|
|
|
+msgstr ""
|
|
|
+"在协程任务函数中,也可以使用 ``await`` 调用其他协程或标准库 `asyncio <https://"
|
|
|
+"docs.python.org/3/library/asyncio.html>`_ 中的可等待对象( `awaitable objects "
|
|
|
+"<https://docs.python.org/3/library/asyncio-task.html#asyncio-awaitables>`_ ):"
|
|
|
+
|
|
|
+#: ../../guide.rst:832
|
|
|
+msgid ""
|
|
|
+" import asyncio\n"
|
|
|
+" from pywebio import start_server\n"
|
|
|
+"\n"
|
|
|
+" async def hello_word():\n"
|
|
|
+" put_text('Hello ...')\n"
|
|
|
+" await asyncio.sleep(1) # await awaitable objects in asyncio\n"
|
|
|
+" put_text('... World!')\n"
|
|
|
+"\n"
|
|
|
+" async def main():\n"
|
|
|
+" await hello_word() # await coroutine\n"
|
|
|
+" put_text('Bye, bye')\n"
|
|
|
+"\n"
|
|
|
+" start_server(main, auto_open_webbrowser=True)"
|
|
|
+msgstr ""
|
|
|
+
|
|
|
+#: ../../guide.rst:851
|
|
|
+msgid ""
|
|
|
+"In coroutine-based session, all input functions defined in the :doc:`pywebio."
|
|
|
+"input </input>` module need to use ``await`` syntax to get the return value. "
|
|
|
+"Forgetting to use ``await`` will be a common error when using coroutine-based "
|
|
|
+"session."
|
|
|
+msgstr ""
|
|
|
+"在基于协程的会话中, :doc:`pywebio.input </input>` 模块中的定义输入函数都需要使"
|
|
|
+"用 ``await`` 语法来获取返回值,忘记使用 ``await`` 将会是在使用基于协程的会话时常"
|
|
|
+"出现的错误。"
|
|
|
+
|
|
|
+#: ../../guide.rst:853
|
|
|
+msgid ""
|
|
|
+"Other functions that need to use ``await`` syntax in the coroutine session are:"
|
|
|
+msgstr "其他在协程会话中也需要使用 ``await`` 语法来进行调用函数有:"
|
|
|
+
|
|
|
+#: ../../guide.rst:855
|
|
|
+msgid ""
|
|
|
+"`pywebio.session.run_asyncio_coroutine(coro_obj) <pywebio.session."
|
|
|
+"run_asyncio_coroutine>`"
|
|
|
+msgstr ""
|
|
|
+
|
|
|
+#: ../../guide.rst:856
|
|
|
+msgid "`pywebio.session.eval_js(expression) <pywebio.session.eval_js>`"
|
|
|
+msgstr ""
|
|
|
+
|
|
|
+#: ../../guide.rst:857
|
|
|
+msgid "`pywebio.session.hold() <pywebio.session.hold>`"
|
|
|
+msgstr ""
|
|
|
+
|
|
|
+#: ../../guide.rst:861
|
|
|
+msgid ""
|
|
|
+"Although the PyWebIO coroutine session is compatible with the ``awaitable "
|
|
|
+"objects`` in the standard library ``asyncio``, the ``asyncio`` library is not "
|
|
|
+"compatible with the ``awaitable objects`` in the PyWebIO coroutine session."
|
|
|
+msgstr ""
|
|
|
+"虽然PyWebIO的协程会话兼容标准库 ``asyncio`` 中的 ``awaitable objects`` ,但 "
|
|
|
+"``asyncio`` 库不兼容PyWebIO协程会话中的 ``awaitable objects`` ."
|
|
|
+
|
|
|
+#: ../../guide.rst:863
|
|
|
+msgid ""
|
|
|
+"That is to say, you can't pass PyWebIO ``awaitable objects`` to the `asyncio`` "
|
|
|
+"functions that accept ``awaitable objects``. For example, the following calls "
|
|
|
+"are **not supported** ::"
|
|
|
+msgstr ""
|
|
|
+"也就是说,无法将PyWebIO中的 ``awaitable objects`` 传入 ``asyncio`` 中的接受 "
|
|
|
+"``awaitable objects`` 作为参数的函数中,比如如下调用是 **不被支持的** ::"
|
|
|
+
|
|
|
+#: ../../guide.rst:865
|
|
|
+msgid ""
|
|
|
+"await asyncio.shield(pywebio.input())\n"
|
|
|
+"await asyncio.gather(asyncio.sleep(1), pywebio.session.eval_js('1+1'))\n"
|
|
|
+"task = asyncio.create_task(pywebio.input())"
|
|
|
+msgstr ""
|
|
|
+
|
|
|
+#: ../../guide.rst:872
|
|
|
+msgid "Concurrency in coroutine-based sessions"
|
|
|
+msgstr "协程会话的并发"
|
|
|
+
|
|
|
+#: ../../guide.rst:874
|
|
|
+msgid ""
|
|
|
+"In coroutine-based session, you can start new thread, but you cannot call "
|
|
|
+"PyWebIO interactive functions in it (`register_thread() <pywebio.session."
|
|
|
+"register_thread>` is not available in coroutine session). But you can use "
|
|
|
+"`run_async(coro) <pywebio.session.run_async>` to execute a coroutine object "
|
|
|
+"asynchronously, and PyWebIO interactive functions can be used in the new "
|
|
|
+"coroutine:"
|
|
|
+msgstr ""
|
|
|
+"在基于协程的会话中,你可以启动线程,但是无法在其中调用PyWebIO交互函数"
|
|
|
+"( `register_thread() <pywebio.session.register_thread>` 在协程会话中不可"
|
|
|
+"用)。\n"
|
|
|
+"但你可以使用 `run_async(coro) <pywebio.session.run_async>` 来异步执行一个协程对"
|
|
|
+"象,新协程内可以使用PyWebIO交互函数:"
|
|
|
+
|
|
|
+#: ../../guide.rst:876
|
|
|
+msgid ""
|
|
|
+" from pywebio import start_server\n"
|
|
|
+" from pywebio.session import run_async\n"
|
|
|
+"\n"
|
|
|
+" async def counter(n):\n"
|
|
|
+" for i in range(n):\n"
|
|
|
+" put_text(i)\n"
|
|
|
+" await asyncio.sleep(1)\n"
|
|
|
+"\n"
|
|
|
+" async def main():\n"
|
|
|
+" run_async(counter(10))\n"
|
|
|
+" put_text('Main coroutine function exited.')\n"
|
|
|
+"\n"
|
|
|
+"\n"
|
|
|
+" start_server(main, auto_open_webbrowser=True)"
|
|
|
+msgstr ""
|
|
|
+
|
|
|
+#: ../../guide.rst:895
|
|
|
+msgid ""
|
|
|
+"`run_async(coro) <pywebio.session.run_async>` returns a `TaskHandle <pywebio."
|
|
|
+"session.coroutinebased.TaskHandle>`, which can be used to query the running "
|
|
|
+"status of the coroutine or close the coroutine."
|
|
|
+msgstr ""
|
|
|
+"`run_async(coro) <pywebio.session.run_async>` 返回一个 `TaskHandle <pywebio."
|
|
|
+"session.coroutinebased.TaskHandle>` ,通过 `TaskHandle <pywebio.session."
|
|
|
+"coroutinebased.TaskHandle>` 可以查询协程运行状态和关闭协程。"
|
|
|
+
|
|
|
+#: ../../guide.rst:900
|
|
|
+msgid ""
|
|
|
+"Similar to thread-based session, in coroutine-based session, when the task "
|
|
|
+"function and the coroutine running through `run_async() <pywebio.session."
|
|
|
+"run_async>` in the session are all finished, the session is closed."
|
|
|
+msgstr ""
|
|
|
+"与基于线程的会话类似,在基于协程的会话中,当任务函数和在会话内通过 `run_async() "
|
|
|
+"<pywebio.session.run_async>` 运行的协程全部结束后,会话关闭。"
|
|
|
+
|
|
|
+#: ../../guide.rst:902
|
|
|
+msgid ""
|
|
|
+"If the close of the session is caused by the user closing the browser, the "
|
|
|
+"behavior of PyWebIO is the same as :ref:`Thread-based session <session_close>`: "
|
|
|
+"After the browser page closed, PyWebIO input function calls that have not yet "
|
|
|
+"returned in the current session will cause `SessionClosedException <pywebio."
|
|
|
+"exceptions.SessionClosedException>`, and subsequent calls to PyWebIO "
|
|
|
+"interactive functions will cause `SessionNotFoundException <pywebio.exceptions."
|
|
|
+"SessionNotFoundException>` or `SessionClosedException <pywebio.exceptions."
|
|
|
+"SessionClosedException>`."
|
|
|
+msgstr ""
|
|
|
+"对于因为用户的关闭浏览器而造成的会话结束,处理逻辑和 :ref:`基于线程的会话 "
|
|
|
+"<session_close>` 一致:\n"
|
|
|
+"此时当前会话内还未返回的PyWebIO输入函数调用将抛出 `SessionClosedException "
|
|
|
+"<pywebio.exceptions.SessionClosedException>` 异常,之后对于PyWebIO交互函数的调用"
|
|
|
+"将会产生 `SessionNotFoundException <pywebio.exceptions."
|
|
|
+"SessionNotFoundException>` 或 `SessionClosedException <pywebio.exceptions."
|
|
|
+"SessionClosedException>` 异常。"
|
|
|
+
|
|
|
+#: ../../guide.rst:904
|
|
|
+msgid ""
|
|
|
+"`defer_call(func) <pywebio.session.defer_call>` also available in coroutine "
|
|
|
+"session."
|
|
|
+msgstr ""
|
|
|
+"协程会话也同样支持使用 `defer_call(func) <pywebio.session.defer_call>` 来设置会"
|
|
|
+"话结束时需要调用的函数。"
|
|
|
+
|
|
|
+#: ../../guide.rst:909
|
|
|
+msgid "Integration with Web Framework"
|
|
|
+msgstr "协程会话与Web框架集成"
|
|
|
+
|
|
|
+#: ../../guide.rst:911
|
|
|
+msgid ""
|
|
|
+"The PyWebIO application that using coroutine-based session can also be "
|
|
|
+"integrated to the web framework."
|
|
|
+msgstr ""
|
|
|
+"基于协程的会话同样可以与Web框架进行集成,只需要在原来传入任务函数的地方改为传入"
|
|
|
+"协程函数即可。"
|
|
|
+
|
|
|
+#: ../../guide.rst:913
|
|
|
+msgid ""
|
|
|
+"However, there are some limitations when using coroutine-based sessions to "
|
|
|
+"integrate into Flask or Django:"
|
|
|
+msgstr "但当前在使用基于协程的会话集成进Flask或Django时,存在一些限制:"
|
|
|
+
|
|
|
+#: ../../guide.rst:915
|
|
|
+msgid ""
|
|
|
+"First, when ``await`` the coroutine objects/awaitable objects in the "
|
|
|
+"``asyncio`` module, you need to use `run_asyncio_coroutine() <pywebio.session."
|
|
|
+"run_asyncio_coroutine>` to wrap the coroutine object."
|
|
|
+msgstr ""
|
|
|
+"一是协程函数内还无法直接通过 ``await`` 直接等待asyncio库中的协程对象,目前需要使"
|
|
|
+"用 `run_asyncio_coroutine() <pywebio.session.run_asyncio_coroutine>` 进行包装。"
|
|
|
+
|
|
|
+#: ../../guide.rst:917
|
|
|
+msgid ""
|
|
|
+"Secondly, you need to start a new thread to run the event loop before starting "
|
|
|
+"a Flask/Django server."
|
|
|
+msgstr ""
|
|
|
+"二是,在启动Flask/Django这类基于线程的服务器之前需要启动一个单独的线程来运行事件"
|
|
|
+"循环。"
|
|
|
+
|
|
|
+#: ../../guide.rst:919
|
|
|
+msgid "Example of coroutine-based session integration into Flask:"
|
|
|
+msgstr "使用基于协程的会话集成进Flask的示例:"
|
|
|
+
|
|
|
+#: ../../guide.rst:921
|
|
|
+msgid ""
|
|
|
+" import asyncio\n"
|
|
|
+" import threading\n"
|
|
|
+" from flask import Flask, send_from_directory\n"
|
|
|
+" from pywebio import STATIC_PATH\n"
|
|
|
+" from pywebio.output import *\n"
|
|
|
+" from pywebio.platform.flask import webio_view\n"
|
|
|
+" from pywebio.platform import run_event_loop\n"
|
|
|
+" from pywebio.session import run_asyncio_coroutine\n"
|
|
|
+"\n"
|
|
|
+" async def hello_word():\n"
|
|
|
+" put_text('Hello ...')\n"
|
|
|
+" await run_asyncio_coroutine(asyncio.sleep(1)) # can't just \"await "
|
|
|
+"asyncio.sleep(1)\"\n"
|
|
|
+" put_text('... World!')\n"
|
|
|
+"\n"
|
|
|
+" app = Flask(__name__)\n"
|
|
|
+" app.add_url_rule('/hello', 'webio_view', webio_view(hello_word),\n"
|
|
|
+" methods=['GET', 'POST', 'OPTIONS'])\n"
|
|
|
+"\n"
|
|
|
+" # thread to run event loop\n"
|
|
|
+" threading.Thread(target=run_event_loop, daemon=True).start()\n"
|
|
|
+" app.run(host='localhost', port=80)"
|
|
|
+msgstr ""
|
|
|
+
|
|
|
+#: ../../guide.rst:946
|
|
|
+msgid ""
|
|
|
+"Finally, coroutine-based session is not available in the Script mode. You "
|
|
|
+"always need to use ``start_server()`` to run coroutine task function or "
|
|
|
+"integrate it to a web framework."
|
|
|
+msgstr ""
|
|
|
+"最后,使用PyWebIO编写的协程函数不支持Script模式,总是需要使用 ``start_server`` "
|
|
|
+"来启动一个服务或者集成进Web框架来调用。"
|
|
|
+
|
|
|
+#: ../../guide.rst:949
|
|
|
+msgid "Last but not least"
|
|
|
+msgstr ""
|
|
|
+
|
|
|
+#: ../../guide.rst:951
|
|
|
+msgid ""
|
|
|
+"This is all features of PyWebIO, you can continue to read the rest of the "
|
|
|
+"documents, or start writing your PyWebIO applications now."
|
|
|
+msgstr ""
|
|
|
+"以上就是PyWebIO的全部功能了,你可以继续阅读接下来的文档,或者立即开始PyWebIO应用"
|
|
|
+"的编写了。"
|
|
|
+
|
|
|
+#: ../../guide.rst:953
|
|
|
+msgid ""
|
|
|
+"Finally, please allow me to provide one more suggestion. When you encounter a "
|
|
|
+"design problem when using PyWebIO, you can ask yourself a question: What would "
|
|
|
+"I do if it is in a terminal program? If you already have the answer, it can be "
|
|
|
+"done in the same way with PyWebIO. If the problem persists or the solution is "
|
|
|
+"not good enough, you can consider the callback mechanism provided by "
|
|
|
+"`put_buttons() <pywebio.output.put_buttons>`."
|
|
|
+msgstr ""
|
|
|
+"最后再提供一条建议,当你在使用PyWebIO遇到设计上的问题时,可以问一下自己:如果在"
|
|
|
+"是在终端程序中我会怎么做?\n"
|
|
|
+"如果你已经有答案了,那么在PyWebIO中一样可以使用这样的方式完成。如果问题依然存在"
|
|
|
+"或者觉得解决方案不够好,\n"
|
|
|
+"你可以考虑使用 `put_buttons() <pywebio.output.put_buttons>` 提供的回调机制。"
|
|
|
+
|
|
|
+#: ../../guide.rst:956
|
|
|
+msgid "OK, Have fun with PyWebIO!"
|
|
|
+msgstr ""
|