我正在使用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_input
和type_input
,它们分别用于每个选项卡,并指定为amount_input
的{{1}}。我怀疑重复使用相同的ID是造成我问题的原因。
有没有一种方法可以将不同id
的输入存储在同一个Python变量中,而不必为每个TextInput
使用不同的kv变量?
答案 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)
(请注意,ListView
和ListAdapter
对象是出于程序目的而添加的,因此在ids
和synchronizeTabContent
中用作submit
的键方法。)