目录
交互式启动器¶
在 1.3.0 版本加入.
自 1.10.0 版本弃用: 交互式启动器已被弃用。
:类 InteractiveLauncher 为用户提供了一个友好的 Python 命令行界面,用于与 App 交互,以便能够交互式地进行原型设计和调试。
备注
Kivy API 设计上,某些函数仅应运行一次或在主事件循环启动前调用。在应用程序运行过程中通常可调用的方法会按预期工作,但动态地覆盖诸如 on_touch() 这类方法则会导致问题。
创建交互式启动器¶
将你的现有 App 子类(可以是生产代码)实例传递给 InteractiveLauncher 构造函数。:
from kivy.interactive import InteractiveLauncher
from kivy.app import App
from kivy.uix.button import Button
class MyApp(App):
def build(self):
return Button(text='Hello Shell')
launcher = InteractiveLauncher(MyApp())
launcher.run()
按下*回车*后,脚本将返回。这允许解释器继续运行。通过InteractiveLauncher实例或提供的:class:SafeMembrane`类实例,可以安全地检查或修改:class:`App。
备注
如果你想测试这个示例,请先启动Python(不带任何文件),这样会得到一个解释器,然后复制粘贴所有行。最后你仍会拥有解释器,同时Kivy应用程序也在运行。
交互式开发¶
IPython 提供了一种快速学习 Kivy API 的方法。通过使用 '.' 运算符并按下 'tab' 键,可以快速列出 App 实例及其所有属性,包括方法和整个控件树。请在 Ipython shell 中尝试以下代码。:
from kivy.interactive import InteractiveLauncher
from kivy.app import App
from kivy.uix.widget import Widget
from kivy.graphics import Color, Ellipse
class MyPaintWidget(Widget):
def on_touch_down(self, touch):
with self.canvas:
Color(1, 1, 0)
d = 30.
Ellipse(pos=(touch.x - d/2, touch.y - d/2), size=(d, d))
class TestApp(App):
def build(self):
return Widget()
i = InteractiveLauncher(TestApp())
i.run()
i. # press 'tab' to list attributes of the app
i.root. # press 'tab' to list attributes of the root widget
# App is boring. Attach a new widget!
i.root.add_widget(MyPaintWidget())
i.safeIn()
# The application is now blocked.
# Click on the screen several times.
i.safeOut()
# The clicks will show up now
# Erase artwork and start over
i.root.canvas.clear()
备注
模块中使用的所有代理都将它们的引用对象存储在 _ref 属性中,如有需要(例如获取文档字符串),可以直接访问该属性。help() 和 type() 会访问代理本身,而非其引用对象。
直接暂停应用程序¶
: InteractiveLauncher 和 SafeMembrane 都持有对 EventLoop 的 'safe' 和 'confirmed' threading.Event 对象的内部引用。您可以使用它们的 safing 方法来手动控制应用程序。
SafeMembrane.safeIn() 将导致应用程序暂停,而 SafeMembrane.safeOut() 将允许暂停的应用程序继续运行。这对于将需要屏幕更新等操作的脚本动作嵌入函数中可能非常有用。
备注
暂停功能是通过 Clocks' 的 schedule_once() 方法实现的,并且在每一帧开始之前发生。
动态添加属性¶
备注
该模块使用线程和对象代理来封装正在运行的 App。如果在线程内部直接引用而未通过提供的代理(proxy)进行访问,可能会导致死锁和内存损坏。
: InteractiveLauncher 可以像普通对象一样向其添加属性,但如果这些属性是在膜外部创建的,它们将不具备线程安全性,因为 Python 解释器中对它们的外部引用不会经过 InteractiveLauncher 从 SafeMembrane 继承的膜行为。
为了使这些外部引用线程安全,只需将它们自身赋值给 SafeMembrane 实例,如下所示:
from kivy.interactive import SafeMembrane
interactiveLauncher.attribute = myNewObject
# myNewObject is unsafe
myNewObject = SafeMembrane(myNewObject)
# myNewObject is now safe. Call at will.
myNewObject.method()
待办事项¶
单元测试、示例,以及更清晰地说明在运行中的应用程序中哪些方法是安全的,这些都会很有帮助。三者兼备则更佳。
可以用上下文管理器风格重写,即:
with safe:
foo()
除了压缩代码之外,还有其他用例吗?
- class kivy.interactive.InteractiveLauncher(app=None, *args, **kwargs)[源代码]¶
基类:
SafeMembrane代理到一个应用程序实例,该实例在线程中启动它,然后返回并作为该线程中应用程序的代理。
- class kivy.interactive.SafeMembrane(ob, *args, **kwargs)[源代码]¶
基类:
object此帮助信息是针对代理对象的。您是否想查看代理所引用对象的帮助?请尝试使用 help(<instance>._ref)。
SafeMembrane 是一个线程安全的代理,它不仅将属性作为新的线程安全对象返回,还确保方法调用是线程安全的,从而防止线程不安全的对象泄露到用户环境中。