#python #kivy #kivymd
#python #kivy #kivymd
Вопрос:
Я использовал код из документов KivyMD о «Динамическом управлении вкладками», чтобы пользователи могли добавлять / удалять вкладки. Однако каждая из этих созданных вкладок, очевидно, идентична, и поэтому виджеты, которые я в нее помещаю, тоже. Это означает, что если я пытаюсь взять идентификатор указанного виджета из, например, вкладки 3, нет способа сделать это, поскольку это тот же идентификатор, что и у виджета на, например, вкладке 1. Вот код:
файл .py
def on_start(self):
self.add_tab()
def get_tab_list(self):
print(self.root.ids.addworkouts.ids.tabs.get_tab_list())
def add_tab(self):
self.index = 1
self.root.ids.addworkouts.ids.tabs.add_widget(Tab(text=f"Exercise {self.index}"))
def remove_tab(self):
self.index -= 1
self.root.ids.addworkouts.ids.tabs.remove_widget(
self.root.ids.addworkouts.ids.tabs.get_tab_list()[0]
)
файл .kv
<AddWorkouts>
name: 'AddWorkouts'
tabs: tabs
BoxLayout:
orientation: 'vertical'
MDToolbar:
title: ' '#app.getWorkoutName()
type: 'top'
left_action_items: [['keyboard-backspace', lambda x: app.goBacktoMyWorkouts()]]
#md_bg_color: app.theme_cls.accent_color
elevation: 10
FloatLayout:
canvas:
Color:
rgba: 0, 0, 0.5, 0.9
Rectangle:
pos: self.pos
size: self.size
MDTabs:
id: tabs
FloatLayout:
canvas:
Color:
rgba: 1, 1, 1, 1
Rectangle:
size: self.size
pos: self.pos
pos_hint: {'center_x': 0.5, 'y': 0.1}
size_hint: 0.8, 0.6
MDTextField:
pos_hint: {'x': 0.05, 'y': 0.8}
size_hint: 0.6, None
hint_text: 'Exercise Name'
helper_text_mode: 'on_focus'
required: 'True'
multiline: False
<Tab>
MDList:
MDBoxLayout:
adaptive_height: True
md_bg_color: 1, 1, 1, 1
MDFlatButton:
text: "ADD EXERCISE"
text_color: 16/255, 167/255, 249/255, 1
on_release: app.add_tab()
MDFlatButton:
text: "REMOVE LAST EXERCISE"
text_color: 16/255, 167/255, 249/255, 1
on_release: app.remove_tab()
Вкладка 1, где входные данные в MDTextField ‘Hi’:
Tab2, где входные данные в MDTextField дублируются с Tab:
Есть ли возможность по-прежнему предоставлять пользователям возможность добавлять и удалять вкладки, но сделать так, чтобы все виджеты (например, MDTextField в файле .kv) имели разные идентификаторы, чтобы я мог получить доступ к пользовательскому вводу из них? Заранее благодарю вас, если этот вопрос был сформулирован неправильно, пожалуйста, просто запросите дополнительную информацию!
Ответ №1:
ids
Заполняются только для виджетов, созданных в kv
правиле. Таким образом, любое, Tab
созданное вне .kv
файла, не будет введено в ids
словарь. Однако вы можете взломать их, ids
изменив свой add_tab()
метод:
import weakref
def add_tab(self):
self.index = 1
new_tab = Tab(text=f"Exercise {self.index}")
new_id = 'tab_' str(self.index)
self.root.ids.addworkouts.ids.tabs.add_widget(new_tab)
self.root.ids.addworkouts.ids.tabs.ids[new_id] = weakref.ref(new_tab)
Это добавляет new_id
к ids
в MDTabs
.
Чтобы сделать это MDTextField
частью Tab
, просто добавьте это в <Tab>
правило. Возможно, вот так:
<Tab>
MDList:
MDTextField:
size_hint: 0.6, None
hint_text: 'Exercise Name'
helper_text_mode: 'on_focus'
required: 'True'
multiline: False
MDBoxLayout:
adaptive_height: True
md_bg_color: 1, 1, 1, 1
MDFlatButton:
text: "ADD EXERCISE"
text_color: 16/255, 167/255, 249/255, 1
on_release: app.add_tab()
MDFlatButton:
text: "REMOVE LAST EXERCISE"
text_color: 16/255, 167/255, 249/255, 1
on_release: app.remove_tab()
Конечно, вы бы удалили MDTextField
(и его окружение FloatLayout
) из <AddWorkouts>
правила.
Комментарии:
1. Это работает, но входные данные в MDTextField по-прежнему дублируются между вкладками. Если я введу «Привет» в текстовое поле на вкладке 1, а затем добавлю другую вкладку, сообщение скопируется. Как мне изменить это, чтобы каждая новая итерация вкладки «обновляла» виджеты?
2.
MDTextField
Это не вTab
, это вFloatLayout
внутриAddWorkouts
Screen
. Таким образом, изменение вкладок никак на это не влияет. Это не дублируется, это просто не является частьюTab
.3. А, ладно, это имеет гораздо больше смысла. Итак, что я хочу, так это отдельные плавающие описания для каждой вкладки, чтобы MDTextField отличался? Как бы я это сделал?
4. спасибо @JohnAnderson, я закрываюсь, чтобы решить ту же проблему, но получаю эту ошибку » Ошибка атрибута: объект ‘MainApp’ не имеет атрибута ‘index’