【问题标题】:How to access children's property dynamically?如何动态访问孩子的财产?
【发布时间】:2018-12-30 05:47:37
【问题描述】:

这是部分代码:

class VectorPatternGrid(GridLayout):
temp_list = []
input_count = 0

def check_coord(self, pointList):
    VectorPatternGrid.input_count += 1      
    if len(VectorPatternGrid.temp_list) >= 2:
        vecArr.assignVector(CustomVector(VectorPatternGrid.temp_list[0], VectorPatternGrid.temp_list[1]))
        for i in range(0, len(VectorPatternGrid.temp_list)):
            del VectorPatternGrid.temp_list[0]

        # Problem occurs here
        for j in range(1, 10):
            self.ids['pat' + str(j)].pressed = False
            self.ids['pat' + str(j)].source = './dot3.png'

    else:
        VectorPatternGrid.temp_list.append(pointList)

确实是kv文件。

在您阅读之前,我真的很抱歉这段代码的可读性差。

#: kivy 1.10.0
<VectorPattern>:
    pressed: self.pressed
    coord: self.coord
    source: self.source

<ProgramScreenManager>:
    VectorConfigScreen:
        id: config
    VectorAuthScreen:
        id: auth

<VectorConfigScreen>:

    BoxLayout:
        id: box
        orientation: 'vertical'
        Label:
            text: "Please set your secret vector pattern."
            font_size: 20
            size_hint: 1, .2
    GridLayout:
        id: grid
        cols: 3
        VectorPattern:
            id: pat1
            coord: [-1,1]
        VectorPattern:
            id: pat2
            coord: [-1,0]
        VectorPattern:
            id: pat3
            coord: [-1,-1]
        VectorPattern:  
            id: pat4
            coord: [0,1]        
        VectorPattern:
            id: pat5
            coord: [0,0]
        VectorPattern:
            id: pat6
            coord: [0,-1]
        VectorPattern:
            id: pat7
            coord: [1,1]
        VectorPattern:  
            id: pat8
            coord: [1,0]        
        VectorPattern:
            id: pat9
            coord: [1,-1]
    Button:
        id: ConfignextBtn
        text: 'next'
        size_hint: 1, .1
        on_press: self.parent.ids.grid.validate_input_count()

<VectorAuthScreen>:
    BoxLayout:
        id: box
        orientation: 'vertical'
        Label:
            text: "Please input your vector pattern."
            size_hint: 1, .2
    GridLayout:
        id: grid
        cols: 3
        VectorPattern:
            id: pat1
            coord: [-1,1]
        VectorPattern:
            id: pat2
            coord: [-1,0]
        VectorPattern:
            id: pat3
            coord: [-1,-1]
        VectorPattern:  
            id: pat4
            coord: [0,1]        
        VectorPattern:
            id: pat5
            coord: [0,0]
        VectorPattern:
            id: pat6
            coord: [0,-1]
        VectorPattern:
            id: pat7
            coord: [1,1]
        VectorPattern:  
            id: pat8
            coord: [1,0]        
        VectorPattern:
            id: pat9
            coord: [1,-1]

和回溯:

Traceback (most recent call last):
File "/home/linux/vectorLockScreenProject/experiment/vectorrecognizer.py", line 79, in <module>
 VectorRecognizer().run()
File "/usr/lib/python2.7/dist-packages/kivy/app.py", line 828, in run
 runTouchApp()
File "/usr/lib/python2.7/dist-packages/kivy/base.py", line 504, in runTouchApp
 EventLoop.window.mainloop()
File "/usr/lib/python2.7/dist-packages/kivy/core/window/window_sdl2.py", line 663, in mainloop
 self._mainloop()
File "/usr/lib/python2.7/dist-packages/kivy/core/window/window_sdl2.py", line 405, in _mainloop
 EventLoop.idle()
File "/usr/lib/python2.7/dist-packages/kivy/base.py", line 342, in idle
 self.dispatch_input()
File "/usr/lib/python2.7/dist-packages/kivy/base.py", line 327, in dispatch_input
 post_dispatch_input(*pop(0))
File "/usr/lib/python2.7/dist-packages/kivy/base.py", line 233, in post_dispatch_input
 listener.dispatch('on_motion', etype, me)
File "kivy/_event.pyx", line 718, in kivy._event.EventDispatcher.dispatch (kivy/_event.c:7726)
File "/usr/lib/python2.7/dist-packages/kivy/core/window/__init__.py", line 1188, in on_motion
 self.dispatch('on_touch_down', me)
File "kivy/_event.pyx", line 718, in kivy._event.EventDispatcher.dispatch (kivy/_event.c:7726)
File "/usr/lib/python2.7/dist-packages/kivy/core/window/__init__.py", line 1204, in on_touch_down
 if w.dispatch('on_touch_down', touch):
File "kivy/_event.pyx", line 718, in kivy._event.EventDispatcher.dispatch (kivy/_event.c:7726)
File "/usr/lib/python2.7/dist-packages/kivy/uix/screenmanager.py", line 1189, in on_touch_down
 return super(ScreenManager, self).on_touch_down(touch)
File "/usr/lib/python2.7/dist-packages/kivy/uix/widget.py", line 457, in on_touch_down
 if child.dispatch('on_touch_down', touch):
File "kivy/_event.pyx", line 718, in kivy._event.EventDispatcher.dispatch (kivy/_event.c:7726)
File "/usr/lib/python2.7/dist-packages/kivy/uix/relativelayout.py", line 288, in on_touch_down
 ret = super(RelativeLayout, self).on_touch_down(touch)
File "/usr/lib/python2.7/dist-packages/kivy/uix/widget.py", line 457, in on_touch_down
 if child.dispatch('on_touch_down', touch):
File "kivy/_event.pyx", line 718, in kivy._event.EventDispatcher.dispatch (kivy/_event.c:7726)
File "/usr/lib/python2.7/dist-packages/kivy/uix/widget.py", line 457, in on_touch_down
 if child.dispatch('on_touch_down', touch):
File "kivy/_event.pyx", line 718, in kivy._event.EventDispatcher.dispatch (kivy/_event.c:7726)
File "/usr/lib/python2.7/dist-packages/kivy/uix/widget.py", line 457, in on_touch_down
 if child.dispatch('on_touch_down', touch):
File "kivy/_event.pyx", line 718, in kivy._event.EventDispatcher.dispatch (kivy/_event.c:7726)
File "/usr/lib/python2.7/dist-packages/kivy/uix/behaviors/button.py", line 151, in on_touch_down
 self.dispatch('on_press')
File "kivy/_event.pyx", line 718, in kivy._event.EventDispatcher.dispatch (kivy/_event.c:7726)
File "/home/linux/vectorLockScreenProject/experiment/vectorrecognizer.py", line 68, in on_press
 tempInstance.check_coord(self.coord)
File "/home/linux/vectorLockScreenProject/experiment/vectorrecognizer.py", line 41, in check_coord
 self.ids['pat' + str(j)].pressed = False
KeyError: 'pat1'

我自己也想弄清楚,但没有一个成功。

所以,我的问题是:

不能使用 self.ids['(string)'] 访问孩子的属性吗? 如果这样, 有没有更好的解决方案?

还有一个额外的问题:

除了写那些重复的“拍”,还有什么更好的办法吗?

感谢任何cmets。

【问题讨论】:

    标签: kivy


    【解决方案1】:

    问题 1

    不能使用 self.ids['(string)'] 访问孩子的属性吗?

    回答 1

    是的,可以使用 self.ids['(string)']

    访问孩子的属性

    Accessing Widgets defined inside Kv lang in your python code

    有一种更简单的方法可以使用 Kv 中的 id 标签访问对象 ids 查找对象。你可以这样做:

    <Marvel>
      Label:
        id: loki
        text: 'loki: I AM YOUR GOD!'
      Button:
        id: hulk
        text: "press to smash loki"
        on_release: root.hulk_smash()
    

    在你的 python 代码中:

    class Marvel(BoxLayout):
    
        def hulk_smash(self):
            self.ids.hulk.text = "hulk: puny god!"
            self.ids["loki"].text = "loki: >_<!!!"  # alternative syntax
    

    问题 2

    除了写那些重复的'拍',还有什么更好的吗 我可以吗?

    回答

    使用 loop 实例化 VectorPattern 并将其添加到布局中。详情请参考示例。

    def create_vector_patterns(self, dt):
        for x in range(len(self.manager.coords)):
            vp = VectorPattern(text=str(self.manager.coords[x]))
            self.ids.grid.add_widget(vp)
    
        # accessing the children
        for child in reversed(self.ids.grid.children):
            print(child, child.text)
    

    示例

    main.py

    ​​>
    from kivy.app import App
    from kivy.uix.screenmanager import ScreenManager, Screen
    from kivy.properties import ListProperty
    from kivy.uix.label import Label
    from kivy.clock import Clock
    
    
    class VectorPattern(Label):
        pass
    
    
    class ProgramScreenManager(ScreenManager):
        coords = ListProperty([])
    
        def __init__(self, **kwargs):
            super(ProgramScreenManager, self).__init__(**kwargs)
            self.coords = [
                [-1, 1], [-1, 0], [-1, -1],
                [0, 1], [0, 0], [0, -1],
                [1, 1], [1, 0], [1, -1]
            ]
    
    
    class VectorConfigScreen(Screen):
    
        def __init__(self, **kwargs):
            super(VectorConfigScreen, self).__init__(**kwargs)
            Clock.schedule_once(self.create_vector_patterns, 1)
    
        def create_vector_patterns(self, dt):
            for x in range(len(self.manager.coords)):
                vp = VectorPattern(text=str(self.manager.coords[x]))
                self.ids.grid.add_widget(vp)
    
            # accessing the children
            for child in reversed(self.ids.grid.children):
                print(child, child.text)
    
    
    
    class VectorAuthScreen(Screen):
    
        def __init__(self, **kwargs):
            super(VectorAuthScreen, self).__init__(**kwargs)
            Clock.schedule_once(self.create_vector_patterns, 1)
    
        def create_vector_patterns(self, dt):
            for x in range(len(self.manager.coords)):
                vp = VectorPattern(text=str(self.manager.coords[x]))
                self.ids.grid.add_widget(vp)
    
            # accessing the children
            for child in reversed(self.ids.grid.children):
                print(child, child.text)
    
    
    class TestApp(App):
    
        def build(self):
            return ProgramScreenManager()
    
    
    if __name__ == "__main__":
        TestApp().run()
    

    test.kv

    #: kivy 1.11.0
    
    <VectorPattern>:
        pressed: self.pressed
        coord: self.coord
        source: self.source
    
    <ProgramScreenManager>:
        VectorConfigScreen:
            id: config
            name: 'config'
    
        VectorAuthScreen:
            id: auth
            name: 'auth'
    
    <VectorConfigScreen>:
        BoxLayout:
            id: box
            orientation: 'vertical'
            Label:
                text: "Please set your secret vector pattern."
                font_size: 20
                size_hint: 1, .2
            GridLayout:
                id: grid
                cols: 3
    
            Button:
                id: ConfignextBtn
                text: 'next'
                size_hint: 1, .1
    
    <VectorAuthScreen>:
        BoxLayout:
            id: box
            orientation: 'vertical'
            Label:
                text: "Please input your vector pattern."
                size_hint: 1, .2
    
            GridLayout:
                id: grid
                cols: 3
    

    输出

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2012-11-30
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2013-02-05
      • 2015-03-08
      相关资源
      最近更新 更多