Я пытаюсь KivyMD создать приложение, и все работало отлично, пока я не столкнулся с проблемой, которую я не могу исправить даже после того, как вчера потратил на это целый день. Я создаю приложение, в котором могу хранить свои тренировки, и столкнулся с проблемой при добавлении двух полей MDTextField. Сначала они не выровнялись должным образом и полностью переместились за пределы boxlayout, затем после некоторого изменения размера (self.minimum_height в файле KV) они теперь доступны для кликов (вы можете видеть изменение текста подсказки), но они не позволяют для любого входа. Вы можете мне помочь, почему MDTextField не работает? Я предполагаю, что это как-то связано с той же проблемой, из-за которой поля были перемещены за пределы boxlayout, но я не понимаю, что вызывает эту проблему.
Вот измененный KV:
NavigationLayout:
id:nav_layout
MainAppScreenManager:
id: screen_manager
AddWorkoutMenu:
<MainAppScreenManager>
<AddWorkoutMenu>
name: "addworkoutmenu"
id: "addworkoutmenu"
workoutname:workoutname
setlist:setlist
BoxLayout:
orientation: 'vertical'
MDToolbar:
title: "Add Workout"
elevation: 10
MDTextField:
id: workoutname
hint_text: "Workout name"
ScrollView:
MDList:
id: setlist
Sets:
id: workoutboxlist
MDRoundFlatIconButton:
id:addset
icon: "plus"
text: "Add set"
on_release:
root.add_set()
<Sets>
id:workoutbox
workoutexerciselist:workoutexerciselist
addbutton:addbutton
reps:reps
rest:rest
orientation: "vertical"
md_bg_color: app.theme_cls.primary_color
radius: 15, 15, 15, 15
padding: "16dp"
spacing: "4dp"
size_hint_y: None
height: self.minimum_height
BoxLayout:
pos_hint: {"center_x": .5, "center_y": 0}
orientation: "horizontal"
MDLabel:
pos_hint: {"center_x": .5, "center_y": .2}
theme_text_color: "Custom"
text_color: [1,1,1,1]
text: root.id
MDIconButton:
pos_hint: {"center_x": .5, "center_y": 0}
icon: "trash-can"
theme_text_color: "Custom"
text_color: [1,1,1,1]
on_release:
self.parent.parent.remove_set()
MDBoxLayout:
size_hint_y: None
height: self.minimum_height / 4
pos_hint: {"center_x": .5, "y": 0}
orientation: "horizontal"
MDLabel:
size_hint: (0.15,None)
pos_hint: {"center_x": .5, "center_y": 0}
theme_text_color: "Custom"
text_color: [1,1,1,1]
text: "Reps:"
MDTextField:
id: reps
size_hint: (0.4,None)
pos_hint: {"center_x": .5, "center_y": 0.1}
spacing: "4dp"
current_hint_text_color: [1,1,1,1]
line_color_normal: [1,1,1,1]
hint_text: "# reps"
MDLabel:
size_hint: (0.1,None)
pos_hint: {"center_x": .5, "center_y": 0}
spacing: "4dp"
theme_text_color: "Custom"
text_color: [1,1,1,1]
text: "Rest:"
MDTextField:
id: rest
size_hint: (0.4,None)
pos_hint: {"center_x": .5, "center_y": 0.1}
spacing: "4dp"
current_hint_text_color: [1,1,1,1]
line_color_normal: [1,1,1,1]
hint_text: "in seconds"
MDList:
id:workoutexerciselist
MDRoundFlatIconButton:
id:addbutton
icon: "plus"
theme_text_color: "Custom"
text_color: [1,1,1,1]
text: "Add exercise"
on_release:
root.open_the_menu()
<WorkoutExerciseListItem>
id: listitem
theme_text_color: "Custom"
text_color: [1,1,1,1]
DeleteItem:
<DeleteItem>
name: "deleteicon"
icon: "close"
theme_text_color: "Custom"
text_color: [1,1,1,1]
on_release:
root.remove()
Вот модифицированный Python:
from kivymd.app import MDApp
from kivymd.theming import ThemableBehavior
from kivymd.toast import toast
from kivymd.uix.list import OneLineIconListItem, MDList, IRightBodyTouch, OneLineRightIconListItem
from kivymd.uix.menu import MDDropdownMenu, RightContent
from kivymd.uix.button import MDIconButton
from kivymd.uix.boxlayout import MDBoxLayout
from kivy.lang import Builder
from kivy.uix.boxlayout import BoxLayout
from kivy.uix.behaviors import ButtonBehavior
from kivy.uix.widget import Widget
from kivy.properties import StringProperty, ObjectProperty, NumericProperty
from kivy.uix.screenmanager import ScreenManager, Screen
from database import DataBaseExercises, DataBaseWorkouts
class AddWorkoutMenu(Screen):
def __init__(self, **kwargs):
super(AddWorkoutMenu, self).__init__(**kwargs)
def add_set(self):
self.ids.setlist.add_widget(Sets(id = ""))
for i in self.ids.setlist.children:
if not hasattr(i, 'menu_1'):
i.create_self()
def save(self):
workout = self.workoutname.text
sets = self.ids.workoutboxlist._sets
if workout != "":
db_workouts.add(workout, sets)
self.parent.current = "workouts"
self.clear_all()
toast("Exercise saved")
else:
toast("Please fill in all information")
def clear_all(self):
self.workoutname.text = ""
for i in list(self.setlist.children):
self.setlist.remove_widget(i)
Sets._ids = 0
self.add_set()
def update_ids(self, removed, total):
if removed != total:
for i in self.ids.setlist.children:
current_number = int(i.id[-1])
if current_number > removed:
current_number -= 1
i.id = "Set " + str(current_number)
class Sets(MDBoxLayout):
_ids = 0
_sets = {}
def __init__(self, **kwargs):
super(Sets, self).__init__(**kwargs)
Sets._ids += 1
self.id = "Set " + str(Sets._ids)
self._sets[self.id] = {}
self._sets[self.id]["Exercise"] = []
self._sets[self.id]["Reps"] = []
self._sets[self.id]["Rest"] = []
def add_selection(self, name):
self.workoutexerciselist.add_widget(WorkoutExerciseListItem(text=name))
self._sets[self.id]["Exercise"].append(name)
print(self._sets[self.id]["Exercise"])
self.update_height()
def update_height(self):
if self.workoutexerciselist.height == 16.0:
self.workoutexerciselist.height = 0.0
self.height = self.minimum_height + self.workoutexerciselist.height
def create_menu(self, text, instance):
menu_items = [{"text": i} for i in text]
return MDDropdownMenu(position = "auto", caller=instance, items=menu_items, width_mult=5, callback=self.set_item)
def create_self(self):
exerciselist = db_exercise.get_all()
self.menu_1 = self.create_menu(exerciselist, self.addbutton)
def update_self(self, value):
new_list = []
new_list.append(value)
for i in self.menu_1.items:
for u in i.values():
new_list.append(u)
self.menu_1 = self.create_menu(new_list, self.addbutton)
def set_item(self, instance):
self.menu_1.on_dismiss()
self.add_selection(instance.text)
self.remove_item(instance.text)
def remove_item(self, item):
new_list = []
for i in self.menu_1.items:
for u in i.values():
if u != item:
new_list.append(u)
self.menu_1 = self.create_menu(new_list, self.addbutton)
def open_the_menu(self):
self.menu_1.open()
def remove_set(self):
number = int(self.id[-1])
self._sets.pop("Set "+str(number))
self.update_set(number)
self.id = "Set 0"
self.parent.parent.parent.parent.parent.update_ids(number, Sets._ids)
Sets._ids -= 1
self.parent.remove_widget(self)
def update_set(self, number):
for i in range(number, Sets._ids):
self._sets["Set " + str(i)] = self._sets["Set " + str(i+1)]
self._sets.pop("Set " + str(i + 1))
def save_reps_and_rest(self):
self._sets[self.id]["Reps"] = self.reps
self._sets[self.id]["Rest"] = self.rest
class WorkoutExerciseListItem(OneLineRightIconListItem):
pass
class DeleteItem(IRightBodyTouch, MDIconButton):
pass
class MainAppScreenManager(ScreenManager):
pass
class MainApp(MDApp):
pass
if __name__ == "__main__":
MainApp().run()