首页 > 解决方案 > Kivy 时钟和弹出窗口

问题描述

如何为 switch_id 和 switch_id_popup 正确创建活动属性,以便可以在 timer_loop 内使用 kivy 时钟创建条件语句?

我在一个类似的问题上得到了很好的反馈(再次感谢 eyllanesc),但由于涉及到弹出窗口,我无法采纳建议。

下面是说明我的问题的草图。我已经用箭头标识了所有有问题的区域。预先感谢您的任何帮助。

from kivy.app import App
from kivy.lang import Builder
from kivy.clock import Clock
import time
from kivy.uix.popup import Popup

theRoot = Builder.load_string('''

<CustomPopup1>:

    StackLayout:
        active2: switch_id_popup.active #<---- switch_id_popup declared here(active2)


        Switch:                         #<---- This switch (switch_id_popup)
            id: switch_id_popup
            size_hint: .5, .5
            active: switch_id_popup.active

        Button:
            text: 'Close'
            on_release: root.dismiss()
            size_hint: .5, .5



StackLayout:
    active1: switch_id.active           #<---- switch_id declared here(active1)
    orientation: 'lr-tb'
    padding: 10
    spacing: 5


    Label:
        text: "Zone 1 Valve"
        size_hint: .25, .1

    Switch:                             #<---- This switch (switch_id)
        id: switch_id
        size_hint: .25, .1
        active: switch_id.active


    Button:
        text: "Program 1"
        on_press: app.open_popup1()
        size_hint: .5,.1

''')


class CustomPopup1(Popup):
    pass

class theApp(App):


    def build(self):
        Clock.schedule_interval(self.timer_loop, 2)
        return theRoot


    def timer_loop(self, dt):  

        if theRoot.active1 and theRoot.active2: #<---- How do I make this work if switch_id_popup is within a popup?
            print("Do something")
        else:
            print("Do nothing")

    def open_popup1(self):
        the_popup = CustomPopup1()
        the_popup.open()


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

标签: pythonkivykivy-language

解决方案


正如我在之前的解决方案中提到的,您应该将每个类视为一个黑盒,并公开允许您获取和建立值的属性。对于 Popup,active 属性必须是类的一部分,而不是内部 StackLayout。另一方面,在 open_popup 方法中,您总是在创建一个新的 Popup,当您关闭它时将删除它,使该属性不可访问,因此我们推断必须有一个具有更大范围的 Popup 对象,因为它必须在外部创建App 类的成员或成为它的成员。最后,active2 不是 theRoot 的属性。

综合以上,得到如下解决方案:

from kivy.app import App
from kivy.lang import Builder
from kivy.clock import Clock
import time
from kivy.uix.popup import Popup

theRoot = Builder.load_string('''
<CustomPopup>:
    active: switch_id_popup.active
    StackLayout:
        Switch:
            id: switch_id_popup
            size_hint: .5, .5
        Button:
            text: 'Close'
            on_release: root.dismiss()
            size_hint: .5, .5

StackLayout:
    active: switch_id.active
    orientation: 'lr-tb'
    padding: 10
    spacing: 5
    Label:
        text: "Zone 1 Valve"
        size_hint: .25, .1
    Switch:
        id: switch_id
        size_hint: .25, .1
    Button:
        text: "Program 1"
        on_press: app.open_popup()
        size_hint: .5,.1

''')

class CustomPopup(Popup):
    pass


class TheApp(App):
    def build(self):
        self.the_popup = CustomPopup()
        Clock.schedule_interval(self.timer_loop, 2)
        return theRoot

    def timer_loop(self, dt):  
        if self.root.active and self.the_popup.active:
            print("Do something")
        else:
            print("Do nothing")

    def open_popup(self):
        self.the_popup.open()


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

推荐阅读