Kivy TextInput赋予了相同的变量

时间:2019-03-07 11:08:23

标签: python kivy

我正在使用Kivy开发带有图形用户界面(GUI)的Python程序。该程序有几个选项卡,其中包含2个TextInput小部件以及一个提交按钮。为了避免每个标签的每个TextInput有一个变量(会产生很多变量),我尝试将来自不同标签的所有对应的TextInput分配给相同的kv变量,即对所有{{ 1}}来自不同的标签。 kv变量的内容提供给两个Python TextInput变量。所有输入类型都相同(即字符串)。

在运行程序并依次在每个选项卡中提供输入时,第一个选项卡的输入为空(使用Python打印时),而第二个选项卡的输入则正常工作。当从kv lang文件的第二个标签中删除重复的ID(即再次使第一个标签的ObjectProperty ID唯一)时,第一个标签的输入将被正确捕获。

因此,似乎在同一kv lang文件中重复相同的id会导致这种错误的输入捕获行为。

这是我的Python脚本的子集(尽可能简化以总结我的问题):

TextInput

这是我的kv lang脚本的子集:

class MyLayout(BoxLayout):

    # 2 inputs per tab
    type_text_input = ObjectProperty()  # 1st input
    amount_text_input = ObjectProperty()  # 2nd input
    all_tab_content = [[] for i in range(9)]
    regular_income_type = ObjectProperty()  # combined input

    def synchronizeTabContent(self, i):
        # Give (back) the value corresponding to the current tab to the ListAdapter
        self.regular_income_type.adapter.data = self.all_tab_content[i]

    def submit(self, i):
        # Get user inputs from the TextInputs
        combined_input = self.type_text_input.text + ":" + self.amount_text_input.text
        # Add string to the ListView and to the whole list
        self.regular_income_type.adapter.data.extend([combined_input])
        self.all_tab_content[i] = self.regular_income_type.adapter.data
        # Reset the ListView
        self.regular_income_type._trigger_reset_populate()


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

        # Set the background color for the window
        Window.clearcolor = (0.1, 0.1, 0.1, 1)
        return MyLayout()


if __name__ == "__main__":
    sample_app = SampleApp()
    sample_app.run()

为第一个选项卡的任何输入存储空字符串的变量为<SubmitButton@Button>: text: "Submit" size_hint_x: 15 MyLayout: <MyLayout>: orientation: "vertical" type_text_input: type_input # variable which is empty in first tab amount_text_input: amount_input # variable which is empty in first tab regular_income_type: students_list_view padding: 10 spacing: 10 #### Some layout code was skipped here #### BoxLayout: orientation: "horizontal" height: 30 BoxLayout: orientation: "horizontal" size_hint_x: .25 TabbedPanelItem: text: "Regular" on_press: root.synchronizeTabContent(4) # ----- First tab ----- BoxLayout: orientation: "vertical" size_hint_x: 1 BoxLayout: size_hint_x: 0.95 size_hint_y: 0.1 height: "40dp" Label: color: (0, 0, 0, 1) text: "Type" TextInput: id: type_input # here is where is suspect the error comes from Label: color: (0, 0, 0, 1) text: "Amount" TextInput: id: amount_input # here is where is suspect the error comes from BoxLayout: # Button box size_hint_y: 0.1 height: "40dp" SubmitButton: on_press: root.submit(4) # ----- End of first tab ----- TabbedPanelItem: text: "Deposit" on_press: root.synchronizeTabContent(5) # ----- Second tab ----- BoxLayout: orientation: "vertical" size_hint_x: 1 BoxLayout: size_hint_x: 0.95 size_hint_y: 0.1 height: "40dp" Label: color: (0, 0, 0, 1) text: "Type" TextInput: id: type_input # here is where is suspect the error comes from Label: color: (0, 0, 0, 1) text: "Amount" TextInput: id: amount_input # here is where is suspect the error comes from BoxLayout: size_hint_y: 0.1 height: "40dp" SubmitButton: on_press: root.submit(5) self.type_text_input。它们对应的kv变量为self.amount_text_inputtype_input,它们分别用于每个选项卡,并指定为amount_input的{​​{1}}。我怀疑重复使用相同的ID是造成我问题的原因。

有没有一种方法可以将不同id的输入存储在同一个Python变量中,而不必为每个TextInput使用不同的kv变量?

1 个答案:

答案 0 :(得分:0)

如@Nearoo所建议,我为每个id分配了不同的TextInput,这是我从Python中的ids变量访问的,因此,我能够检索所有用户在单个Python变量中输入,而不使用ObjectProperty变量。 ids变量是一个字典,其关键字是kv lang脚本中提供的id,其值在此情况下为TextInput

最终的简化Python代码为:

class MyLayout(BoxLayout):

    # store all tab content
    all_tab_content = [[] for i in range(9)]

    def synchronizeTabContent(self, i):
        # Give (back) the value corresponding to the current tab to the ListAdapter
        self.ids["regular_income{}".format(i)].adapter.data = self.all_tab_content[i]

    def submit(self, i):
        # Get user inputs from the TextInputs
        combined_input = self.ids["type_input{}".format(i)].text + self.sep + self.ids["amount_input{}".format(i)].text
        # Add string to the ListView and to the whole list
        self.ids["regular_income{}".format(i)].adapter.data.extend([combined_input])
        self.all_tab_content[i] = self.ids["regular_income{}".format(i)].adapter.data
        # Reset the ListView
        self.ids["regular_income{}".format(i)]._trigger_reset_populate()


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

        # Set the background color for the window
        Window.clearcolor = (0.1, 0.1, 0.1, 1)
        return MyLayout()


if __name__ == "__main__":
    sample_app = SampleApp()
    sample_app.run()

最终的简化kv lang代码为:

<SubmitButton@Button>:
    text: "Submit"
    size_hint_x: 15

MyLayout:

<MyLayout>:
    orientation: "vertical"
    padding: 10
    spacing: 10

    #### Some layout code was skipped here ####

    BoxLayout:
        orientation: "horizontal"
        height: 30

        BoxLayout:
            orientation: "horizontal"
            size_hint_x: .25
            TabbedPanelItem:
                text: "Regular"
                on_press: root.synchronizeTabContent(4)

                # ----- First tab -----
                BoxLayout:
                    orientation: "vertical"
                    size_hint_x: 1
                    BoxLayout:
                        size_hint_x: 0.95
                        size_hint_y: 0.1
                        height: "40dp"

                        Label:
                            color: (0, 0, 0, 1)
                            text: "Type"
                        TextInput:
                            id: type_input4  # each id is unique
                        Label:
                            color: (0, 0, 0, 1)
                            text: "Amount"
                        TextInput:
                            id: amount_input4  # each id is unique
                    BoxLayout:  # Button box
                        size_hint_y: 0.1
                        height: "40dp"
                        SubmitButton:
                            on_press: root.submit(4)
                                    ListView:
                                        size_hint_y: 0.2
                                        id: regular_income4
                                        adapter:
                                            ListAdapter(data=[], cls=main.StudentListButton)


            # ----- End of first tab -----

            TabbedPanelItem:
                text: "Deposit"
                on_press: root.synchronizeTabContent(5)

                # ----- Second tab -----
                BoxLayout:
                    orientation: "vertical"
                    size_hint_x: 1
                    BoxLayout:
                        size_hint_x: 0.95
                        size_hint_y: 0.1
                        height: "40dp"

                        Label:
                            color: (0, 0, 0, 1)
                            text: "Type"
                        TextInput:
                            id: type_input5  # each id is unique
                        Label:
                            color: (0, 0, 0, 1)
                            text: "Amount"
                        TextInput:
                            id: amount_input5  # each id is unique
                    BoxLayout:
                        size_hint_y: 0.1
                        height: "40dp"
                        SubmitButton:
                            on_press: root.submit(5)
                                    ListView:
                                        size_hint_y: 0.2
                                        id: regular_income5
                                        adapter:
                                            ListAdapter(data=[], cls=main.StudentListButton)

(请注意,ListViewListAdapter对象是出于程序目的而添加的,因此在idssynchronizeTabContent中用作submit的键方法。)