python kivy在for循环中生成链接到jsonstore项目的按钮

时间:2018-07-22 09:15:56

标签: python kivy

我正在使用for循环为jsonstore中的每个键生成一个按钮。 所有按钮都正确添加到布局中,并且button.text是正确的,但是当按钮调用回调时,它们都链接到相同的键。 (最后一个键)

代码如下:

def show_saved_conditions(*args,**kwargs):

    self.label7 = Label(text = str(self.store[self.btns.text], size_hint = (.3,.3), pos_hint = {'x':.3,'y':.5}, color = (0,0,1,1)))
    self.layout.add_widget(self.label7)

def view_saved_conditions(*args, **kwargs):

    x = 0
    y = 0

    for i in self.store.keys():

        self.btns = (Button(text = i, size_hint = (.2,.1), pos_hint = {'x':x,'y':y}, on_release = show_saved_conditions))
        self.layout.add_widget(self.btns)

        x +=.2

        if x >= 1:
            y+=.1
            x = 0

很确定以前曾问过这个问题,但我找不到足够具体的帖子与我联系。

提前谢谢...

2 个答案:

答案 0 :(得分:0)

问题-始终参考最后一个按钮

show_saved_conditions()方法中,它始终使用self.btns.text,这是添加到布局的最后一个按钮。

self.label7 = Label(text = str(self.store[self.btns.text], size_hint = (.3,.3), pos_hint = {'x':.3,'y':.5}, color = (0,0,1,1)))

解决方案

在示例中,它演示了on_touch_down事件。

Touch event basic

  

默认情况下,触摸事件将分派给所有当前显示的事件   小部件。这意味着小部件会接收触摸事件,无论它是否发生   不在他们的物理区域内。

     

为了提供最大的灵活性,Kivy派遣了   所有小部件的事件,并让他们决定如何对它们做出反应。   如果您只想响应小部件内的触摸事件,则可以   只需检查:

def move(self, touch):
    if self.collide_point(*touch.pos):
        # The touch has occurred inside the widgets area. Do stuff!
        pass

示例

main.py

from kivy.app import App
from kivy.uix.gridlayout import GridLayout
from kivy.uix.button import Button


class CreateButton(Button):

    def on_touch_down(self, touch):
        if self.collide_point(*touch.pos):
            if touch.button == "right":
                print(self.id, "right mouse clicked")
            elif touch.button == "left":
                print(self.id, "left mouse clicked")
            else:
                print(self.id)
            return True
        return super(CreateButton, self).on_touch_down(touch)


class OnTouchDownDemo(GridLayout):

    def __init__(self, **kwargs):
        super(OnTouchDownDemo, self).__init__(**kwargs)
        self.build_board()

    def build_board(self, *args):
        # make 9 buttons in a grid
        for i in range(0, 9):
            button = CreateButton(id=str(i), text=str(i))
            self.add_widget(button)


class OnTouchDownApp(App):

    def build(self):
        return OnTouchDownDemo()


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

ontouchdown.kv

#:kivy 1.11.0

<CreateButton>:
    font_size: 50

<OnTouchDownDemo>:
    rows: 3
    cols: 3
    row_force_default: True
    row_default_height: 150
    col_force_default: True
    col_default_width: 150
    padding: [10]
    spacing: [10]

输出

enter image description here

答案 1 :(得分:0)

您的*args方法的show_saved_conditions()自变量包含被按下的Button实例。这样的方法可能是:

def show_saved_conditions(self, btn_instance):

    self.label7 = Label(text = str(self.store[btn_instance.text], size_hint = (.3,.3), pos_hint = {'x':.3,'y':.5}, color = (0,0,1,1)))
    self.layout.add_widget(self.label7)

由于您在方法中使用了self,因此我假设这是一个实例方法,正确的第一个arg是self。如果它不是实例方法,则只需删除self arg,但是该方法从何处获取self的值?

当然,此方法每次执行时都会覆盖self.label7