在本文中,我们将讨论如何在浏览器中使用Brython,通过实现一个Base64计算器来在浏览器中进行实验,使用文档对象模型应用程序接口和其他仅在JavaScript中可用的功能。

Brython中的文档对象模型应用程序接口

为了使用Brython中可用的文档对象模型操作进行实验,我们将构建一个用于将字符串编码为Base64的表单。最终的输出表单将如下所示:

188-1.png

让我们创建一个HTML文件,并将其命名为index.html:

例如:

<!DOCTYPE html >  
<html>  
  <head>  
    <meta charset = "utf-8"/>  
    <link  
      rel = "stylesheet"  
      href = "https://cdnjs.cloudflare.com /ajax/libs/pure/2.0.3/pure-min.min.css"  
      integrity = "sha256-jYujp4Kf07YDuUF9i1MHo4AnpXUKuHxIUXH7CrHxdKw="  
      crossorigin = "anonymous" />  
    <script  
      src = "https://cdnjs.cloudflare.com /ajax/libs/brython/3.8.9/brython.min.js"  
      integrity = "sha256-U56d9Sn/Gtf1meSBXazW81LM1bUeyc1jFuoY3CBu6A8="  
      crossorigin = "anonymous">  
    </script>  
    <script  
      src = "https://cdnjs.cloudflare.com /ajax/libs/brython  
/3.8.9/brython_stdlib.min.js"  
      integrity = "sha256 twMHOlRBOpBkpyGFeXIBWoJqTpqf76Zp8HExOelwyRc="  
      crossorigin = "anonymous"  
      defer>  
    </script>  
    <script src = "main.py" type="text/python" defer>  
</script>  
    <style>  
      body { padding: 30px; }  
    </style>  
  </head>  
  <body onload="brython()">  
    <form class="pure-form" onsubmit="return false;">  
      <fieldset>  
        <legend>Base64 Calculator</legend>  
        <input type = "text" id = "text-src" placeholder = "Text to Encode" autocomplete="off"/>  
        <button type = "submit" id = "submit" class = "pure-button pure-button-primary">Ok  
</button>  
        <button id = "clear-btn" class = "pure-button">Clear  
</button>  
      </fieldset>  
    </form>  
    <div id="b64-display">  
</div>  
  </body>  
</html>  

上述HTML代码加载了静态资源,定义了UI布局,并启动了Python的编译:

  • 第7行:加载PureCSS样式表以改善默认的HTML样式。
  • 第9行:加载Brython引擎的缩小版本。
  • 第12行:加载Brython标准库的缩小版本。
  • 第14行:加载main.py,它将处理此静态HTML页面的动态逻辑。
  • 第21行:描述输入字段。此字段将接受要编码的字符串作为参数。
  • 第22到第25行:定义了默认按钮,该按钮将触发页面的主要逻辑。用户可以在main.py中看到此逻辑的实现。
  • 第26行:定义了清除页面上的数据和元素的按钮。这将在main.py中实现。
  • 第29行:声明要用作表格占位符的div。

与之关联的Python代码是main.py。

例如:

from browser import document, html, alert  
import base64  
  
b64_map = {}  
  
  
def base64_compute(evt):  
    value = document[" text-src "].value  
    if not value:  
        alert(" You need to enter a value ")  
        return  
    if value in b64_map:  
        alert(  
            f" The base64 value of '{value}' already exists: '{b64_map[value]}' "  
        )  
        return  
    b64data = base64.b64encode(value.encode()).decode()  
    b64_map[value] = b64data  
    display_map()  
  
  
def clear_map(evt):  
    b64_map.clear()  
    document[" b64-display "].clear()  
  
  
def display_map():  
    table = html.TABLE(Class = "pure-table")  
    table <= html.THEAD(html.TR(html.TH(" Text ") + html.TH(" Base64 ")))  
    table <= (html.TR(html.TD(key) + html.TD(b64_map[key])) for key in b64_map)  
    base64_display = document[" b64-display "]  
    base64_display.clear()  
    base64_display <= table  
    document[" text-src "].value = ""  
  
  
document[" submit "].bind("click", base64_compute)  
document[" clear-btn "].bind("click", clear_map)  

上面的Python程序显示了回调函数的定义以及操作DOM的机制:

  • 第1行:导入与文档对象模型(DOM)交互以及Brython模块和库的模块。
  • 第2行:导入base64,它在Brython的标准库中可用,即brython_stdlib.min.js。
  • 第4行:声明字典,用户将在HTML页面运行时用于存储数据。
  • 第6行定义了事件处理程序,即base64_compute(),它将对ID为text-src的输入字段中输入的文本进行Base64编码。
  • 第7行:获取具有text-src标识的DOM元素的值。
  • 第18行:定义事件处理程序,即clear_map(),它将清除页面上的数据和数据呈现。
  • 第22行:定义display_map(),它将从b64_map中取得的数据以页面形式显示。
  • 第26行:获取具有ID text-src的DOM元素。
  • 第29行:清除具有ID text-src的DOM元素的值。
  • 第31行:将提交按钮的单击事件绑定到base64_compute()。
  • 第32行:将clear-btn按钮的单击事件绑定到clear_map()。

为了操作DOM,Brython将使用两个运算符:

  1. <=是一个新运算符,主要特定于Brython。它将子元素添加到节点中。我们在display_map()中使用了它,该函数在第22行定义。
  2. +是Element.insertAdjacementHTML('afterend')的替代方式,用于添加兄弟节点。

我们可以在display_map()的上述语句中看到这两个运算符的使用:

table <= html.THEAD(html.TR( html.TH(" Text ") + html.TH(" Base64 "))) 

上述命令可以翻译为“将表元素和包含两个相邻表数据单元格元素的表头元素添加到表中”。在浏览器中呈现的HTML程序如下:

<table>  
<thead>  
<tr><th>Text</th><th>Base64</th></tr>  
</thead>  
</table>  

上面的HTML代码显示了表元素的表头行的嵌套结构。我们还可以以更易读的方式编写此代码:

<table>  
  <thead>  
    <tr>  
      <th>  
Text  
      </th>  
      <th>  
Base64  
      </th>  
    </tr>  
  </thead>  
</table>  

为了在Brython控制台中观察结果,我们可以输入以下代码块:

from browser import html  
table = html.TABLE()  
table <= html.THEAD(html.TR( html.TH(" Text ") + html.TH(" Base64 ")))  
table.outerHTML  

输出:

'<table> <thead> <tr> <th> Text </th> <th> Base64 </th> </tr> </thead> </table>'

要执行整个代码,我们需要启动网站服务器。与之前一样,我们在与两个文件main.html和index.html相同的目录中启动了内置Python网站服务器。

例如:

$ python3 -m http.server  

输出:

Serving HTTP on :: port 8080 (http://[::]:8080/) ...

启动网站服务器后,将浏览器指向http://localhost:8080。此页面将如下所示:

188-2.png

在Brython中导入文件

用户可以使用import来访问JavaScript中的Python或Brython模块和库。

Python模块和库是位于其项目的根文件夹或包含_init_.py文件的子文件夹中的具有.py扩展名的文件。要在Brython程序中导入Python模块,用户需要启动网站服务器。

如果用户想要了解如何将Python模块导入到Brython代码中,可以查看"How to install Brython"文章中的"Installation by using PyPI"部分。他们需要创建并激活Python虚拟环境,安装Brython,然后修改index.html。

例如:

<!doctype html>  
<html>  
  
<head>  
<meta charset = " utf-8 ">  
<script type = " text/javascript " src = " brython.js ">  
</script>  
<script type = " text/javascript " src = " brython_stdlib.js ">  
</script>  
</head>  
  
<body onload = " brython() ">  
  
<script type = " text/python ">  
from browser import document, html, window  
import sys  
import functional  
  
selection = functional.take(10, range(10000))  
numbers = ', '.join([ str(x) for x in selection ])  
  
document <= html.P(f"{sys.version=}")  
document <= html.P(f"{numbers=}")  
</script>  
  
</body>  
  
</html>  

上述HTML文件将公开从浏览器的核心引擎、sys的标准库以及本地Python模块functional中导入的模块。functional.py的内容如下:

import itertools  
  
def take(n, iterable):  
    "Return first n items of the iterable as a list"  
    return list(itertools.islice(iterable, n))  

此模块实现了take(),它是itertools中的一个方法,用于返回给定可迭代对象的前n个元素。它依赖于itertools.slice()。

如果用户尝试使用浏览器从文件系统中打开index.html,那么他们将在浏览器控制台中看到以下错误:

Traceback (most recent call last):  
         File file:///Users/User Name/brython/code /import/index.html/__main__  
----> 3 in <module>  
    import functional  
ModuleNotFoundError: functional  

在导入所需的Python模块之后,需要启动本地网站服务器。首先启动本地网站服务器,然后在浏览器中打开http://localhost:8080。用户将看到以下HTML页面:

188-3.png

如果有运行中的网站服务器,那么浏览器将能够在执行导入functional的操作后获取functional.py模块。数字和sys.version值的结果是通过浏览器内嵌和渲染的最后两个Python脚本插入到HTML文件中的。

减小导入大小

在前面示例项目的目录中,为了减小导入的JavaScript库和模块的大小,用户可以使用Brython-cli并使用-module选项。此方法还可用于将Python模块预编译为JavaScript。

例如:

$ brython-cli -modules 

输出:

Create brython_modules.js with all the modules used by the application
searching brython_stdlib.js...
finding packages...
script in html index.html

这将用于生成brython_modules.js,然后用户可以修改index.html文件的head元素。

例如:

<head>  
 <meta charset="utf-8">  
 <script type="text/javascript" src="brython.js">  
</script>  
 <script type="text/javascript" src="brython_modules.js">  
</script>  
 </head>

第5行将脚本源的原始形式从brython_stdlib.js更改为brython_modules.js。

用户可以使用浏览器打开index.html,或者将浏览器指向减小到相同HTML页面的本地服务器。用户可以注意到以下几点:

  1. 即使没有运行网站服务器,他们也可以在浏览器中减小HTML页面。
  2. 他们不需要分发functional.py文件,因为该程序现在已转换为JavaScript,然后捆绑在brython_modules.js中。
  3. 用户不需要加载brython_stdlib.js。

命令行工具brython-cli -modules将提供从标准库中删除不必要代码的解决方案。然后,它将Python模块编译为JavaScript程序。这将有助于用户应用程序的页面,从而减小资源下载的大小。

结论

在本文中,我们讨论了如何在浏览器中使用Brython,通过使用Base64计算器进行实验,该计算器用于使用文档对象模型应用程序接口在浏览器中进行实验。我们还解释了用户如何导入Python文件到Brython中以及如何减小导入文件的大小。

标签: Tkinter教程, Tkinter安装, Tkinter库, Tkinter入门, Tkinter学习, Tkinter入门教程, Tkinter, Tkinter进阶, Tkinter指南, Tkinter学习指南, Tkinter进阶教程, Tkinter编程