是否可以使用Clock安排Kivy StringProperty set()方法?

时间:2019-01-09 12:22:14

标签: string methods properties set kivy

我想延迟Kivy屏幕管理器的过渡,例如,我可以这样做:

#!/usr/bin/env python

from kivy.app import App
from kivy.lang import Builder
from kivy.uix.floatlayout import FloatLayout
from kivy.properties import StringProperty
from kivy.uix.button import Button
from kivy.clock import Clock

Builder.load_string('''
#: kivy 1.9.2
#: import sm kivy.uix.screenmanager
#: set base_font_size 25

<MainWidget>:
    manager: screen_manager

    ScreenManager:
        id: screen_manager
        transition: sm.NoTransition()
        Screen:
            name: 'screen_one'  
            Button:
                text: 'Screen 1, press to switch to Screen 2'
                font_size: base_font_size
                on_press:
                    root.manager.current = 'screen_two'
                    root.statusmsg = 'Screen 2, press to launch Armageddon'

        Screen:
            name: 'screen_two'
            Button:
                text: root.statusmsg
                font_size: base_font_size
                disabled: True if root.statusmsg == 'Busy launching Armageddon' else False # prevent multiple activation
                on_press:
                    root.deliver_payload()

''')


class MainWidget(FloatLayout):

    statusmsg = StringProperty()

    def __init__(self, **kwargs):
        super(MainWidget, self).__init__(**kwargs)

    def deliver_payload(self, dt=0):
        if not dt: # called via on_press
            self.statusmsg = 'Busy launching Armageddon'
            # launch Armageddon here
            Clock.schedule_once(self.deliver_payload, 2)
        else: # scheduled via Clock
            self.manager.current = 'screen_one'


class MyApp(App):
    def build(self):
        mw=MainWidget() 
        return mw


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

但是,manager.current是Kivy StringProperty,我应该能够使用set()方法为其分配一个新值,并可能通过Clock来安排它,例如Clock.schedule_once(lambda dt:self.manager.property('current')。set(??,'screen_one'),2)。 我找不到Kivy StringProperty set()方法的文档。看来该方法需要两个参数,第一个参数的类型必须为kivy._event.EventDispatcher-根据我尝试随机猜测时得到的回溯信息。任何人都可以指向一些文档或set()方法的使用示例吗?

编辑:我意识到我没有弄清楚最终要做什么-我在问是否可以使用Kivy Clock安排Kivy属性set()方法。例如,我可以像这样切换Kivy BooleanProperty:

if self.property('myboolean').get(self):
    self.property('myboolean').set(self, False)
else:
    self.property('myboolean').set(self, True)

但是我无法使用Clock安排方法。以下行未产生任何错误,但也没有任何作用:

Clock.schedule_once(lambda dt: self.property('myboolean').set(self, False),0)

在使用Kivy StringProperty set()方法的情况下,我什至无法弄清楚第一个参数需要是什么,因此无法尝试使用Clock进行调度。

进一步编辑: 尽管根据文档,屏幕管理器“当前”是StringProperty,但其行为似乎有所不同。使用StringProperty,我可以执行以下操作:

self.property('statusmsg').set(self, 'Armageddon now')

但是,使用manager.current尝试类似的操作不会成功:

self.manager.property('current').set(self.manager, 'aux_screen')

错误消息是:

   self.manager.property('current').set(self.manager, 'screen_one')
TypeError: Argument 'obj' has incorrect type (expected kivy._event.EventDispatcher, got kivy.weakproxy.WeakProxy)

令人困惑。

2 个答案:

答案 0 :(得分:0)

您可以像在代码中一样,只需执行StringProperty,即可为self.manager.current = 'some string'设置新值。

答案 1 :(得分:0)

我偶然偶然发现了Kivy: Changing screens in screen manager with an on_press event(谢谢,Tshirtman),我现在有一个答案。以下更改为我提供了我想要的-直接安排屏幕更改的功能(即无需调用中间方法):

def deliver_payload(self):
    self.statusmsg = 'Busy launching Armageddon'
    Clock.schedule_once(lambda dt: self.manager.setter('current')(self.manager,'screen_one'), 2)

看来,要为屏幕管理器的“当前”属性分配一个新值,正确使用的方法是“设置”方法(而不是我尝试使用的“设置”方法)。