说明

这是之前的文章,更新以匹配 CodeLab Adapter 3.0

近期我们在CodeLab Adapter制作了不少有趣的案例.得益于我们最近构建的json extension,我们可以让Python与Scratch3.0之间传递任意复杂的数据结构。如此一来,我们就可以将任意的Python程序接入Scratch3.0中。

以下是摘自CodeLab Adapter gallery页面的一些有趣的案例:

人脸地标: 在Python中使用dlib采集我的脸部地标,之后将这些数据完整地传给Scratch,接着在Scratch中解析这些数据,将其用于绘图,在Scratch中实时绘制出我的脸部特征点。当然我们也可以用于任何其他用途。这个策略是完全通用的,意味着可以将Python构建的任意AI项目积木化。当然这个过程有些细节需要注意,诸如numpy描述的矩阵得先转化为Python数据结构,如果你对此感兴趣,我们可以邮件里细说:)

不喜欢微信的聊天界面?没关系,我们在Scratch中自己new一个。它真实可用,你可以用于与朋友聊天。当然你也可以通过组合积木将微信用于控制智能家居。

所有的这些都发生在Scratch中!

下边我们将以简单的例子,展示这种交互方式。

Python -> Scratch

我们先来展示数据从Python流向Scratch。

我们希望将以下数据发布给Scratch:

1
2
3
4
{
    "hello": "world",
    "numbers": [1,2,3]
}

我们先来看看CodeLab Adapter extension插件应该怎么写

Python extensions

提示

推荐使用 Jupyterlab插件 编辑代码。

~/codelab_adapter/extensions目录下(linux/mac适用。windows用户可以点击菜单栏->扩展->打开扩展目录), 创建extension_test.py插件,内容如下

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
import time
from codelab_adapter.core_extension import Extension

class DemoExtension(Extension):
    NODE_ID = "eim"
    def __init__(self):
        super().__init__()


    def run(self):
        # run 会被作为线程调用
        while self._running:
            message = self.message_template()
            message["payload"]["content"] = {"hello": "world","numbers": [1,2,3]}
            self.publish(message)
            time.sleep(1)
export = DemoExtension

Scratch

当extension_test插件在CodeLab Adapter中被加载后,在Scratch一侧,我们就可以利用EIM插件与Json插件 来取回我们从Python中发过来的消息。

scratch接收到{"hello": "world","numbers": [1,2,3]},它成为EIM receive message积木的内容。

我们可以使用Json积木来解析消息体。

以上两个例子展示了我们可以解析任意的json结构。值得注意的是,列表的下标从1开始(不是0),这是为了遵循Scratch社区对列表的操作风格(用户更容易理解)。

Scratch -> Python

接下来,我们将展示,从Scratch发往Python的消息。对大部分用户来说,发送字符串就够了。对于高级用户,他们可能希望传递更复杂的数据结构。当然没问题!

一个典型的用例是:前端使用颜色控件选择颜色,将RGB信息发往后端

1
2
3
4
5
{
    "R": 255,
    "G": 0,
    "B": 0
}

Scratch

我们在Scratch需要做的是

更理想的做法其实是在Scratch中制作一个新的extension,构建颜色选择器,这部分涉及前端的调整,官方还没放出教程,这种优化问题我们以后再讨论。如果你已经在EIM中构建好了这个积木,要迁移到新的extension UI上,是非常简单的。核心的通信过程并没有变化,我们已经为你都做好了。构建EIM的目的是给出一种通用的积木,你无需编写js代码,动态性在消息中,而不是固化在积木,这种特性,对开发和扩展极为有利。 在我们以后的microworldrealworld案例中,我们将演示这种架构将带来多么大的灵活性和可能性,我们认为Scratch从Smalltalk学到的重要东西,正是通过消息来解耦,并获得扩展能力,CodeLab Adapter将继续发挥这个原则。

你可能会问,如何将你定制的的EIM积木分发给用户?目前你可以下载下来,之后让用户用这个文件初始化项目便可。在以后,我们会允许你发布到云端,用户打开特定链接就行。

everything is a message

Python extensions

创建extension_test.py插件,内容如下

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
from codelab_adapter.core_extension import Extension

class DemoExtension(Extension):
    NODE_ID = "eim"
    def __init__(self):
        super().__init__()

    def extension_message_handle(self, topic, payload):
        self.logger.info(f'eim message-> {payload}')
        payload["content"] = "ok"
        self.publish({"payload": payload})

    def run(self):
        while self._running:
            time.sleep(1)

export = DemoExtension

当extension_test插件在codelab_adapter中被加载后吗, 新开一个命令行运行tail -f ~/codelab_adapter/info.log | grep extension_test (mac/linux适用,windows用户参考windows用户),查看接收到的来自Scratch的消息:

至此演示完毕。

对了如果你希望在一个插件中双向传递数据,你需要多线程,可以参考我们的例子:extension_eim.py

注意

大多数情况下,你只需要发送和接受字符串就够了,这种风格与Scratch内置的广播极为相近。是典型的事件驱动风格。

这篇教程主要针对那些希望去拓展Scratch的人。当你需要将一些复杂的程序接入Scratch(例如接入AI或者接入微信,如我们制作的例子),它会对你有帮助。