首页 > 解决方案 > 如何动态访问孩子的财产?

问题描述

这是代码的一部分:

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)'] 访问孩子的财产吗?如果是这样,有没有更好的解决方案?

和额外的问题:

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

任何意见表示赞赏。

标签: kivy

解决方案


问题 1

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

答案 1

是的,可以使用 self.ids['(string)'] 访问孩子的财产

在 Python 代码中访问 Kv lang 中定义的小部件

有一种更简单的方法可以使用 ids 查找对象来访问 Kv 中带有 id 标签的对象。您可以按如下方式执行此操作:

<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

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

回答

使用循环实例化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)

例子

主文件

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()

测试.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

输出

图像01


推荐阅读