屏幕管理器

_images/screenmanager.gif

在 1.4.0 版本加入.

屏幕管理器是一个专门用于管理应用程序中多个屏幕的控件。默认的 ScreenManager 一次只显示一个 Screen,并使用 TransitionBase 来从一个屏幕切换到另一个屏幕。

支持多种过渡效果,这些效果基于改变屏幕坐标/缩放比例,甚至可以使用自定义着色器执行华丽的动画。

基本用法

让我们构建一个包含4个命名屏幕的Screen Manager。在创建屏幕时,你必须为其指定一个名称:

from kivy.uix.screenmanager import ScreenManager, Screen

# Create the manager
sm = ScreenManager()

# Add few screens
for i in range(4):
    screen = Screen(name='Title %d' % i)
    sm.add_widget(screen)

# By default, the first screen added into the ScreenManager will be
# displayed. You can then change to another screen.

# Let's display the screen named 'Title 2'
# A transition will automatically be used.
sm.current = 'Title 2'

默认的 ScreenManager.transition 是一个 SlideTransition,其选项包括 directionduration

请注意,默认情况下,一个 Screen 不显示任何内容:它只是一个 RelativeLayout。您需要将该类用作您自己屏幕的根部件,最佳方式是继承该类。

警告

由于 Screen 是一个 RelativeLayout,理解 常见陷阱 非常重要。

以下是一个包含“菜单屏幕”和“设置屏幕”的示例:

from kivy.app import App
from kivy.lang import Builder
from kivy.uix.screenmanager import ScreenManager, Screen

# Create both screens. Please note the root.manager.current: this is how
# you can control the ScreenManager from kv. Each screen has by default a
# property manager that gives you the instance of the ScreenManager used.
Builder.load_string("""
<MenuScreen>:
    BoxLayout:
        Button:
            text: 'Goto settings'
            on_press: root.manager.current = 'settings'
        Button:
            text: 'Quit'

<SettingsScreen>:
    BoxLayout:
        Button:
            text: 'My settings button'
        Button:
            text: 'Back to menu'
            on_press: root.manager.current = 'menu'
""")

# Declare both screens
class MenuScreen(Screen):
    pass

class SettingsScreen(Screen):
    pass

class TestApp(App):

    def build(self):
        # Create the screen manager
        sm = ScreenManager()
        sm.add_widget(MenuScreen(name='menu'))
        sm.add_widget(SettingsScreen(name='settings'))

        return sm

if __name__ == '__main__':
    TestApp().run()

改变方向

ScreenManager 的一个常见用例涉及使用 SlideTransition,它向右滑动到下一个屏幕,向左滑动到上一个屏幕。基于之前的示例,可以通过以下方式实现::

Builder.load_string("""
<MenuScreen>:
    BoxLayout:
        Button:
            text: 'Goto settings'
            on_press:
                root.manager.transition.direction = 'left'
                root.manager.current = 'settings'
        Button:
            text: 'Quit'

<SettingsScreen>:
    BoxLayout:
        Button:
            text: 'My settings button'
        Button:
            text: 'Back to menu'
            on_press:
                root.manager.transition.direction = 'right'
                root.manager.current = 'menu'
""")

高级用法

从1.8.0版本开始,您可以通过使用:meth:`~ScreenManager.switch_to`方法动态切换到新屏幕、更改过渡选项并移除之前的屏幕::

sm = ScreenManager()
screens = [Screen(name='Title {}'.format(i)) for i in range(4)]

sm.switch_to(screens[0])
# later
sm.switch_to(screens[1], direction='right')

请注意,此方法会将屏幕添加到 ScreenManager 实例中,如果您的屏幕已经添加到此实例,则不应使用此方法。若要切换到已添加的屏幕,应使用 current 属性。

更改过渡效果。

默认情况下,您可以使用多种过渡效果,例如:

  • NoTransition - 立即切换屏幕,无动画效果。

  • SlideTransition - 从任意方向将屏幕滑入/滑出

  • CardTransition - 新屏幕滑入覆盖旧屏幕,或旧屏幕滑出露出新屏幕,具体取决于模式。

  • SwapTransition - iOS 交换过渡效果的实现

  • FadeTransition - 用于屏幕淡入/淡出的着色器

  • WipeTransition - 用于从右向左擦除屏幕的着色器

  • FallOutTransition - 一种着色器效果,旧屏幕“落下”并逐渐变得透明,从而显露出其背后的新屏幕。

  • RiseInTransition - 一种着色器效果,新屏幕从屏幕中心升起,同时从透明渐变为不透明。

您可以通过更改 ScreenManager.transition 属性轻松切换过渡效果:

sm = ScreenManager(transition=FadeTransition())

备注

目前,所有基于Shader的过渡效果均未使用抗锯齿技术。这是因为它们依赖于FBO,而FBO本身不具备处理超采样的逻辑。这是一个已知问题,我们正在致力于一个透明的实现方案,旨在达到与直接在屏幕上渲染相同的效果。

更具体地说,如果在动画过程中看到文字边缘锐利,这是正常的。

class kivy.uix.screenmanager.CardTransition[源代码]

基类:SlideTransition

类似Android 4.x应用抽屉界面动画的卡片过渡效果。

它支持4个方向,如SlideTransition:左、右、上、下,以及两种模式:弹出(pop)和推入(push)。如果激活推入模式,前一个屏幕不会移动,新屏幕从指定方向滑入。如果激活弹出模式,当前一个屏幕已经位于ScreenManager的位置时,前一个屏幕会滑出。

在 1.10 版本加入.

mode

指示过渡是否应将屏幕推入或弹出ScreenManager。

  • “push”表示屏幕沿指定方向滑入。

  • “pop”表示屏幕沿指定方向滑出。

mode 是一个 OptionProperty,默认值为 'push'。

start(manager)[源代码]

(内部)启动过渡。此方法由 ScreenManager 自动调用。

class kivy.uix.screenmanager.FadeTransition[源代码]

基类:ShaderTransition

基于片段着色器的淡入淡出过渡效果。

fs

要使用的片段着色器。

fs 是一个 StringProperty,默认值为 None。

class kivy.uix.screenmanager.FallOutTransition[源代码]

基类:ShaderTransition

新屏幕从屏幕中心“落下”的过渡效果,逐渐缩小并变得更加透明,直至消失,从而显露出其背后的新屏幕。模仿了流行/标准的Android过渡动画。

在 1.8.0 版本加入.

duration

过渡的持续时间(秒),替换 TransitionBase 的默认值。

duration 是一个 NumericProperty,默认值为 .15(即 150 毫秒)。

fs

要使用的片段着色器。

fs 是一个 StringProperty,默认值为 None。

class kivy.uix.screenmanager.NoTransition[源代码]

基类:TransitionBase

无过渡效果,立即切换到下一个屏幕,无延迟或动画。

在 1.8.0 版本加入.

duration

过渡的持续时间(秒)。

duration 是一个 NumericProperty,默认值为 .4(即 400 毫秒)。

在 1.8.0 版本发生变更: 默认持续时间已从700毫秒改为400毫秒。

class kivy.uix.screenmanager.RiseInTransition[源代码]

基类:ShaderTransition

新屏幕从屏幕中心升起,逐渐变大并从透明变为不透明,直至填满整个屏幕的过渡效果。模拟了流行/标准的Android过渡动画。

在 1.8.0 版本加入.

duration

过渡的持续时间(秒),替换 TransitionBase 的默认值。

duration 是一个 NumericProperty,默认值为 .2(即 200 毫秒)。

fs

要使用的片段着色器。

fs 是一个 StringProperty,默认值为 None。

class kivy.uix.screenmanager.Screen(**kw)[源代码]

基类:RelativeLayout

Screen 是一个旨在与 ScreenManager 配合使用的元素。更多信息请参阅模块文档。

事件:
on_pre_enter: ()

当屏幕即将被使用时触发的事件:进入动画已开始。

on_enter: ()

屏幕显示时触发的事件:进入动画已完成。

on_pre_leave: ()

当屏幕即将被移除时触发的事件:离开动画已开始。

on_leave: ()

屏幕被移除时触发的事件:离开动画已完成。

在 1.6.0 版本发生变更: 新增了 on_pre_enteron_enteron_pre_leaveon_leave 事件。

manager

ScreenManager 对象,在屏幕被添加到管理器时设置。

manager 是一个 ObjectProperty,默认值为 None,只读。

name

屏幕的名称,在 ScreenManager 中必须是唯一的。此名称用于 ScreenManager.current

name 是一个 StringProperty,默认值为 ''。

transition_progress

表示当前过渡(如有进行中)完成情况的值。

如果过渡正在进行中,无论模式如何,值都会从0变为1。若想了解是进入动画还是离开动画,请查看 transition_state

transition_progress 是一个 NumericProperty,默认值为 0。

transition_state

表示过渡状态的值:

  • 如果过渡效果将显示你的屏幕,则使用 'in'。

  • 如果过渡效果将隐藏你的屏幕,则使用'out'。

过渡完成后,状态将保持其最后一个值(进入或退出)。

transition_state 是一个 OptionProperty,默认值为 'out'。

class kivy.uix.screenmanager.ScreenManager(**kwargs)[源代码]

基类:FloatLayout

屏幕管理器。这是控制您的 Screen 堆栈和内存的主要类。

默认情况下,管理器一次只显示一个屏幕。

add_widget(widget, *args, **kwargs)[源代码]

在 2.1.0 版本发生变更: 将参数 screen 重命名为 widget

clear_widgets(children=None, *args, **kwargs)[源代码]

在 2.1.0 版本发生变更: 参数 screens 已重命名为 children

current

当前显示屏幕的名称,或要显示的屏幕。

from kivy.uix.screenmanager import ScreenManager, Screen

sm = ScreenManager()
sm.add_widget(Screen(name='first'))
sm.add_widget(Screen(name='second'))

# By default, the first added screen will be shown. If you want to
# show another one, just set the 'current' property.
sm.current = 'second'

current 是一个 StringProperty,默认值为 None。

current_screen

包含当前显示的屏幕。您不得手动更改此属性,请改用 current

current_screen 是一个 ObjectProperty,默认值为 None,只读。

get_screen(name)[源代码]

返回与名称关联的屏幕组件,如果未找到则引发 ScreenManagerException 异常。

has_screen(name)[源代码]

如果找到了名为 name 的屏幕,则返回 True。

在 1.6.0 版本加入.

next()[源代码]

从屏幕列表中返回下一个屏幕的名称。

on_motion(etype, me)[源代码]

当接收到一个运动事件时调用。

参数:
etypestr

事件类型,取值为"begin"、"update"或"end"之一。

meMotionEvent

收到运动事件

返回:

bool 类型,值为 True 时停止事件分发。

在 2.1.0 版本加入.

警告

此方法目前仍处于实验阶段,只要此警告存在,它就一直保持实验状态。

on_touch_down(touch)[源代码]

接收触摸按下事件。

参数:
touchMotionEvent

收到触摸事件。该触摸位于父级坐标系中。关于坐标系统的讨论,请参阅 relativelayout

返回:

bool 如果为 True,触摸事件的派发将停止。如果为 False,事件将继续派发给控件树中的其余部分。

on_touch_move(touch)[源代码]

接收触摸移动事件。触摸坐标位于父坐标系中。

更多信息请参见 on_touch_down()

on_touch_up(touch)[源代码]

接收触摸抬起事件。触摸坐标位于父级坐标系中。

更多信息请参见 on_touch_down()

previous()[源代码]

返回屏幕列表中上一个屏幕的名称。

remove_widget(widget, *args, **kwargs)[源代码]

从该部件的子部件中移除一个部件。

参数:
widget: Widget

要从我们的子控件列表中移除的控件。

>>> from kivy.uix.button import Button
>>> root = Widget()
>>> button = Button()
>>> root.add_widget(button)
>>> root.remove_widget(button)
screen_names

所有已添加的 Screen 控件名称列表。该列表为只读。

screens_names 是一个 AliasProperty,且为只读属性。当屏幕列表发生变化或某个屏幕的名称改变时,该属性会自动更新。

screens

所有已添加的 Screen 控件列表。请勿手动修改此列表,应使用 add_widget 方法进行添加。

screens 是一个 ListProperty,默认值为 [],只读。

switch_to(screen, **options)[源代码]

将一个新的或现有的屏幕添加到ScreenManager并切换到该屏幕。之前的屏幕将被“切换离开”。`options`是:attr:`transition`选项,这些选项将在动画发生前被修改。

如果没有可用的先前屏幕,该屏幕将被用作主屏幕::

sm = ScreenManager()
sm.switch_to(screen1)
# later
sm.switch_to(screen2, direction='left')
# later
sm.switch_to(screen3, direction='right', duration=1.)

如果当前有任何动画正在进行,它将被停止并被此动画替换:应避免这种情况,因为动画会显得很奇怪。请使用 switch_to()current 中的一种,但不要同时使用两者。

如果 screen 名称与当前屏幕存在任何冲突,该名称将被更改。

transition

用于动画化从当前屏幕过渡到下一个屏幕的过渡对象。

例如,如果你想在幻灯片之间使用 WipeTransition:

from kivy.uix.screenmanager import ScreenManager, Screen,
WipeTransition

sm = ScreenManager(transition=WipeTransition())
sm.add_widget(Screen(name='first'))
sm.add_widget(Screen(name='second'))

# by default, the first added screen will be shown. If you want to
# show another one, just set the 'current' property.
sm.current = 'second'

transition 是一个 ObjectProperty,默认值为 SlideTransition

在 1.8.0 版本发生变更: 默认过渡效果已从 SwapTransition 更改为 SlideTransition

exception kivy.uix.screenmanager.ScreenManagerException[源代码]

基类:Exception

ScreenManager 的异常。

class kivy.uix.screenmanager.ShaderTransition[源代码]

基类:TransitionBase

使用Shader在2个屏幕之间进行动画过渡的Transition类。默认情况下,此类不分配任何片段/顶点着色器。如果你想为过渡创建自己的片段着色器,你需要自行声明头部,并包含“t”、“tex_in”和“tex_out”统一变量::

# Create your own transition. This shader implements a "fading"
# transition.
fs = """$HEADER
    uniform float t;
    uniform sampler2D tex_in;
    uniform sampler2D tex_out;

    void main(void) {
        vec4 cin = texture2D(tex_in, tex_coord0);
        vec4 cout = texture2D(tex_out, tex_coord0);
        gl_FragColor = mix(cout, cin, t);
    }
"""

# And create your transition
tr = ShaderTransition(fs=fs)
sm = ScreenManager(transition=tr)
add_screen(screen)[源代码]

(内部)用于向 ScreenManager 添加一个屏幕。

clearcolor

设置Fbo的ClearColor颜色。

在 1.9.0 版本加入.

clearcolor 是一个 ColorProperty,默认值为 [0, 0, 0, 1]。

在 2.0.0 版本发生变更: ListProperty 更改为 ColorProperty

fs

要使用的片段着色器。

fs 是一个 StringProperty,默认值为 None。

remove_screen(screen)[源代码]

(内部)用于从 ScreenManager 中移除一个屏幕。

stop()[源代码]

(内部)停止过渡。此方法由 ScreenManager 自动调用。

vs

要使用的顶点着色器。

vs 是一个 StringProperty,默认值为 None。

class kivy.uix.screenmanager.SlideTransition[源代码]

基类:TransitionBase

滑动过渡,可用于从任意方向展示新屏幕:左、右、上或下。

direction

过渡的方向。

direction 是一个 OptionProperty,默认值为 'left'。可选值为 'left'、'right'、'up' 或 'down'。

class kivy.uix.screenmanager.SwapTransition(**kwargs)[源代码]

基类:TransitionBase

类似iOS过渡效果的交换过渡,当新窗口出现在屏幕上时。

add_screen(screen)[源代码]

(内部)用于向 ScreenManager 添加一个屏幕。

start(manager)[源代码]

(内部)启动过渡。此方法由 ScreenManager 自动调用。

class kivy.uix.screenmanager.TransitionBase[源代码]

基类:EventDispatcher

TransitionBase 用于在 ScreenManager 中为两个屏幕之间的切换添加动画效果。该类作为其他实现(如 SlideTransitionSwapTransition)的基类。

事件:
on_progress:过渡对象,进度浮点数

在过渡动画期间触发。

on_complete:过渡对象

当过渡完成时触发。

add_screen(screen)[源代码]

(内部)用于向 ScreenManager 添加一个屏幕。

duration

过渡的持续时间(秒)。

duration 是一个 NumericProperty,默认值为 .4(即 400 毫秒)。

在 1.8.0 版本发生变更: 默认持续时间已从700毫秒改为400毫秒。

is_active

指示过渡当前是否处于活动状态。

is_active 是一个 BooleanProperty,默认值为 False,且为只读属性。

manager

ScreenManager 对象,在屏幕被添加到管理器时设置。

manager 是一个 ObjectProperty,默认值为 None,只读。

remove_screen(screen)[源代码]

(内部)用于从 ScreenManager 中移除一个屏幕。

screen_in

包含要显示的屏幕的属性。由 ScreenManager 自动设置。

screen_in 是一个 ObjectProperty,默认值为 None。

screen_out

包含要隐藏的屏幕的属性。由 ScreenManager 自动设置。

screen_out 是一个 ObjectProperty,默认值为 None。

start(manager)[源代码]

(内部)启动过渡。此方法由 ScreenManager 自动调用。

stop()[源代码]

(内部)停止过渡。此方法由 ScreenManager 自动调用。

class kivy.uix.screenmanager.WipeTransition[源代码]

基类:ShaderTransition

基于片段着色器的擦除过渡效果。

fs

要使用的片段着色器。

fs 是一个 StringProperty,默认值为 None。