首页 > 解决方案 > Kivy 中程序生成的按钮

问题描述

所以,我希望我的按钮在释放时调用一个函数,以便我的标签可见。如您所见,按钮的 on_release 设置为 buttonPress 我想这样做,但无论我按下哪个按钮,它都会将最后一个标签传递给函数。我怎样才能解决这个问题?有一个更好的方法吗?

    def buttonPress(self, label):
        print("hi")
        print(label)
        label.height = '50dp'
        label.font_size = '20sp'


    def on_pre_enter(self, *args):
        mainLayout = RelativeLayout()
        self.add_widget(mainLayout)
        scroll = ScrollView(do_scroll_x = False,pos_hint={"top":0.8,"center_x":0.75})
        infoLayout = GridLayout(cols = 1, size_hint = (0.5, None))
        mainLayout.add_widget(scroll)
        scroll.add_widget(infoLayout)

        files = glob.glob("user/*.txt")
        InfoWidgetButtonArray = []
        InfoWidgetLabelArray = []

        for x in range(len(files)):
            InfoWidgetLabelArray.append(Label(text="hello mate", size_hint_y=None,height = '0dp', font_size='0sp', color = (0, 0, 0, 1), id=str(x)))
            print(InfoWidgetLabelArray[x])
            InfoWidgetButtonArray.append(Button(text=files[x][5:][:-4], font_size=14, size_hint=(0.5, None), height=30,on_release=lambda lambdaFunction: self.buttonPress(InfoWidgetLabelArray[x])))
            infoLayout.add_widget(InfoWidgetButtonArray[x])
            infoLayout.add_widget(InfoWidgetLabelArray[x])

这是一个最小的可重现示例:

from kivy.app import App
from kivy.uix.screenmanager import ScreenManager, Screen
from kivy.uix.button import Button
from kivy.uix.gridlayout import GridLayout
from kivy.core.window import Window
from kivy.uix.relativelayout import RelativeLayout
from kivy.uix.scrollview import ScrollView
from kivy.uix.label import Label
from kivy.uix.widget import Widget


Window.clearcolor = (1,1,1,1)

class InfoScreen(Screen, Widget):
    new = True
    def buttonPress(self, label):
        print("hi")
        print(label)
        label.height = '50dp'
        label.font_size = '20sp'


    def on_pre_enter(self, *args):
        mainLayout = RelativeLayout()
        self.add_widget(mainLayout)
        scroll = ScrollView(do_scroll_x = False,pos_hint={"top":0.8,"center_x":0.75})
        infoLayout = GridLayout(cols = 1, size_hint = (0.5, None))
        mainLayout.add_widget(scroll)
        scroll.add_widget(infoLayout)


        InfoWidgetButtonArray = []
        InfoWidgetLabelArray = []

        for x in range(2):
            InfoWidgetLabelArray.append(Label(text="hello mate", size_hint_y=None,height = '0dp', font_size='0sp', color = (0, 0, 0, 1), id=str(x)))
            print(InfoWidgetLabelArray[x])
            InfoWidgetButtonArray.append(Button(text="name"+str(x), font_size=14, size_hint=(0.5, None), height=30,on_release=lambda lambdaFunction: self.buttonPress(InfoWidgetLabelArray[x])))
            infoLayout.add_widget(InfoWidgetButtonArray[x])
            infoLayout.add_widget(InfoWidgetLabelArray[x])


        SpacingButton = Button(text='Hello world', font_size=14, size_hint=(0.5, None), height=50, color=(0, 0, 0, 0), background_color=(0,0,0,0))
        infoLayout.add_widget(SpacingButton)

        infoLayout.bind(minimum_height=infoLayout.setter('height'))



sm = ScreenManager()
sm.add_widget(InfoScreen(name='Info'))


class TestApp(App):
    def build(self):

        return sm

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

标签: pythonpython-3.xkivy

解决方案


我认为您正在寻找functools模块中的部分功能。它在 for 循环中绑定输入并返回您希望它具有的实际功能。

from kivy.app import App
from kivy.uix.screenmanager import ScreenManager, Screen
from kivy.uix.button import Button
from kivy.uix.gridlayout import GridLayout
from kivy.core.window import Window
from kivy.uix.relativelayout import RelativeLayout
from kivy.uix.scrollview import ScrollView
from kivy.uix.label import Label
from kivy.uix.widget import Widget
from kivy.properties import StringProperty

from functools import partial #Changed This

Window.clearcolor = (1,1,1,1)

class InfoScreen(Screen, Widget):
    new = True
    def buttonPress(self, label, *args):
        print("hi")
        print(label)
        label.height = '50dp'
        label.font_size = '20sp'

    def on_pre_enter(self, *args):
        mainLayout = RelativeLayout()
        self.add_widget(mainLayout)
        scroll = ScrollView(do_scroll_x = False, pos_hint={"top":0.8,"center_x":0.75}, size_hint_max_y=300) #To enable scrolling be sure to set a maximal value, or have enough buttons to cover the whole window
        infoLayout = GridLayout(cols = 1, size_hint = (0.5, None))
        mainLayout.add_widget(scroll)
        scroll.add_widget(infoLayout)


        InfoWidgetButtonArray = []
        InfoWidgetLabelArray = []

        for x in range(5):
            InfoWidgetLabelArray.append(Label(text="hello mate", size_hint_y=None,height = '0dp', font_size='0sp', color = (0, 0, 0, 1), id=str(x)))
            print(InfoWidgetLabelArray[x])
            InfoWidgetButtonArray.append(Button(text="name"+str(x), font_size=14, size_hint=(0.5, None), height=30, on_release=partial(self.buttonPress, InfoWidgetLabelArray[x]))) #Changed This
            infoLayout.add_widget(InfoWidgetButtonArray[x])
            infoLayout.add_widget(InfoWidgetLabelArray[x])


        SpacingButton = Button(text='Hello world', font_size=14, size_hint=(0.5, None), height=50, color=(0, 0, 0, 0), background_color=(0,0,0,0))
        infoLayout.add_widget(SpacingButton)

        infoLayout.bind(minimum_height=infoLayout.setter('height'))

sm = ScreenManager()
sm.add_widget(InfoScreen(name='Info'))

class TestApp(App):
    def build(self):
        return sm

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

希望这就是您要找的东西,我花了一些时间重新阅读了这个问题,然后才希望能理解。


推荐阅读