简体   繁体   English

如何在Kivy(Python3)中动态创建多个函数?

[英]How to create multiple functions dynamically in Kivy (Python3)?

Situation情况

I am creating a meeting finder app that will search through a JSON file and return a list of multiple meeting dictionaries.我正在创建一个会议查找器应用程序,它将搜索 JSON 文件并返回多个会议词典的列表。 And I want to create buttons for each of the meetings so that I could know more information about the meeting or join the meeting.我想为每个会议创建按钮,以便我可以了解有关会议的更多信息或加入会议。 Since I need to query the meetings list, so I don't know how many meetings button will be there.由于我需要查询会议列表,所以我不知道会有多少个会议按钮。 I need to generate and bind those buttons dynamically.我需要动态生成和绑定这些按钮。

Python Code Python代码

Only adding that part of the code which is causing the problem.只添加导致问题的那部分代码。

class MeetingDisplayer(Screen):
    def __init__(self,back,info,**kwargs):
        super().__init__(**kwargs)
        self.back = back
        self.info = info   # this is the meetings list which contains multiple meeting dictionaries.

        self.headings = [] # this will contain the text of the buttons
        for meeting in self.info:
            meeting_subject = meeting["meeting_subject"]
            meeting_organizer = meeting["meeting_organizer"]
            time = meeting["time"]
            heading = f"{meeting_subject} | {meeting_organizer} | {time}"
            self.headings.append([heading,None])
            
        
        self.scroller = ScrollView()
        self.scroller.pos_hint = {"x": 0.1, "top": 0.75}
        self.scroller.size_hint = (0.8, 0.63)
        
        self.info_grid = GridLayout()
        self.info_grid.cols = 1
        if len(self.headings) > 20:
            self.info_grid.size_hint = 1, 2
        elif len(self.headings) > 10:
            self.info_grid.size_hint = 1, 1.4
        elif len(self.headings) > 5: 
            self.info_grid.size_hint = 1, 0.8
        else:
            self.info_grid.size_hint = 1, 0.35
        
        i = -1
        for heading in self.headings:
            i += 1
            heading[1] = Button(text = heading[0], font_size = 15, color = (1,1,1,1), background_color = (0/255, 153/255, 204/255, 1), on_release = lambda x: self.find_function(i))
            self.info_grid.add_widget(heading[1])

        self.scroller.add_widget(self.info_grid)
        self.add_widget(self.scroller)
     
        
    def find_function(self, i):
        sm.add_widget(MeetingInformation(self.info, name = "MeetingInformation"))
        MeetingInformation_screen = sm.get_screen('MeetingInformation')
        setattr(MeetingInformation_screen, "index", i)
        sm.transition = SlideTransition(direction = "left")
        sm.current = "MeetingInformation"


class MeetingInformation(Screen):
    def __init__(self, meeting_list, **kwargs):
        super().__init__(**kwargs)
        self.meeting_list  = meeting_list

    def on_pre_enter(self):
        print(self.index)
        meeting = self.meeting_list[self.index]        

        self.info_grid = GridLayout()
        self.info_grid.cols = 2
        self.info_grid.size_hint = 0.9, 0.4
        self.info_grid.pos_hint = {"x": 0.05, "top": 0.67}
        self.category_label = Button(text = "Category:", font_size = 14, color = (1,1,1,1), background_color = (0/255, 153/255, 204/255, 1))
        self.info_grid.add_widget(self.category_label)
        self.category_value = Label(text = meeting["category"], font_size = 14, color = (0,0,0,1))
        self.info_grid.add_widget(self.category_value)
        self.time_label = Button(text = "Time:", font_size = 14, color = (1,1,1,1), background_color = (0/255, 153/255, 204/255, 1))
        self.info_grid.add_widget(self.time_label)
        self.time_value = Label(text = meeting["time"], font_size = 14, color = (0,0,0,1))
        self.info_grid.add_widget(self.time_value)
        self.subject_label = Button(text = "Subject:", font_size = 14, color = (1,1,1,1), background_color = (0/255, 153/255, 204/255, 1))
        self.info_grid.add_widget(self.subject_label)
        self.subject_value = Label(text = meeting["meeting_subject"], font_size = 14, color = (0,0,0,1))
        self.info_grid.add_widget(self.subject_value)
        self.organizer_label = Button(text = "Organizer:", font_size = 14, color = (1,1,1,1), background_color = (0/255, 153/255, 204/255, 1))
        self.info_grid.add_widget(self.organizer_label)
        self.organizer_value = Label(text = meeting["meeting_organizer"], font_size = 14, color = (0,0,0,1))
        self.info_grid.add_widget(self.organizer_value)
        self.meeting_id_label = Button(text = "Meeting ID:", font_size = 14, color = (1,1,1,1), background_color = (0/255, 153/255, 204/255, 1))
        self.info_grid.add_widget(self.meeting_id_label)
        self.meeting_id_value = Label(text = str(meeting["meeting_id"]), font_size = 14, color = (0,0,0,1))
        self.info_grid.add_widget(self.meeting_id_value)
        self.passcode_label = Button(text = str("Meeting Passcode:"), font_size = 14, color = (1,1,1,1), background_color = (0/255, 153/255, 204/255, 1))
        self.info_grid.add_widget(self.passcode_label)
        self.passcode_value = Label(text = meeting["passcode"], font_size = 14, color = (0,0,0,1))
        self.info_grid.add_widget(self.passcode_value)
        self.activation_status_label = Button(text = "Activation Status:", font_size = 14, color = (1,1,1,1), background_color = (0/255, 153/255, 204/255, 1))
        self.info_grid.add_widget(self.activation_status_label)
        self.activation_status_value = Label(text = str(meeting["active"]), font_size = 14, color = (0,0,0,1))
        self.info_grid.add_widget(self.activation_status_value)
        self.add_widget(self.info_grid)

But the problem is when I clicked a button, I can only get the last button widget that I added.但问题是当我点击一个按钮时,我只能得到我添加的最后一个按钮小部件。 I mean the i variable which is the index attribute is set to a fixed number [the index of the last button] and it can not identify which button is pressed.我的意思是索引属性的i变量设置为固定数字[最后一个按钮的索引],它无法识别按下了哪个按钮。

Some pictures which can help一些可以帮助的图片

all buttons are here所有按钮都在这里

after pressing the first button按下第一个按钮后

after pressing the second button按下第二个按钮后

Question问题

How can I bind the buttons with the function in a dynamic manner so that each time I press a button, I get the exact index of that button or display the exact information?如何以动态方式将按钮与 function 绑定,以便每次按下按钮时都能获得该按钮的确切索引或显示确切信息?

Try changing:尝试改变:

heading[1] = Button(text = heading[0], font_size = 15, color = (1,1,1,1), background_color = (0/255, 153/255, 204/255, 1), on_release = lambda x: self.find_function(i))

to:至:

heading[1] = Button(text = heading[0], font_size = 15, color = (1,1,1,1), background_color = (0/255, 153/255, 204/255, 1), on_release = lambda x, j=i: self.find_function(j))

The lambda function evaluates the i when the lambda is called (by the button press). lambda function 在调用 lambda 时评估i (通过按下按钮)。 Changing to lambda x, j=i: self.find_function(j) forces the evaluation of i when the `lambda is created.更改为lambda x, j=i: self.find_function(j)在创建 `lambda 时强制评估i

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM