如何动态访问孩子的财产?

Posted

技术标签:

【中文标题】如何动态访问孩子的财产?【英文标题】: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。

【问题讨论】:

【参考方案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

输出

【讨论】:

以上是关于如何动态访问孩子的财产?的主要内容,如果未能解决你的问题,请参考以下文章

从某些父母那里退回那些他们的孩子的某些财产等于某个价值的记录?

使绝对定位的孩子随他们的上级动态调整大小

如何在 recyclerview 适配器中将动态视图添加到 android 布局

可扩展的列表视图子项动态计数

Flash AS3 动态添加子项。命名它们并调用每个分开的问题

具有一个静态和一个动态子级的堆栈视图?