获取 KivyMD 上的小部件索引(MDList)
Get index of a widget on KivyMD (MDList)
我正在尝试构建一个在 Python 和 KivyMD 中具有计划管理器的应用程序。代码的第一页是显示日程表的地方,另一页是您将添加信息的地方。在第二页填写表格后,仪表板 window 将更新,注册的 activity 信息将添加到 MDList 小部件中。左上MDCard保存活动的平均时间,右上MDCard保存活动注册数量。
如果 he/she 在注册时出错(向右滑动 MDList 项目并单击垃圾桶图标),用户将有机会删除以前注册的 activity。当然,删除后需要更新小部件值。我的问题是在尝试更新活动的平均时间时出现的:要计算所有金额保存到列表中的平均值,我想做的是获取 MDList 中删除的项目的索引。所以我可以相应地删除金额并进行准确的计算。 (其实我只是选择了要删除的索引为0,所以删除的项永远是列表中的第一项。
Python 文件:
from kivymd.app import MDApp
from kivy.uix.screenmanager import ScreenManager, Screen
from kivymd.toast import toast
from kivymd.uix.menu import MDDropdownMenu
from kivy.clock import Clock
from kivy.config import Config
from kivy.core.window import Window
from kivy.utils import platform
from kivy.properties import StringProperty
from kivymd.uix.card import MDCardSwipe
from kivymd.uix.button import MDIconButton, MDTooltip
from kivymd.uix.behaviors.toggle_behavior import MDToggleButton
from kivymd.uix.button import MDRectangleFlatButton
if platform not in ('android', 'ios'):
Config.set('graphics', 'resizable', '0')
Window.size = (600, 700)
class TooltipMDIconButton(MDIconButton, MDTooltip):
pass
class MyToggleButton(MDRectangleFlatButton, MDToggleButton):
def __init__(self, **kwargs):
super().__init__(**kwargs)
self.background_down = self.theme_cls.primary_light
class SwipeToDeleteItem(MDCardSwipe):
text = StringProperty()
secondary_text = StringProperty()
def remove_item(self, instance):
dash = MDApp.get_running_app().root.get_screen('dash')
dash.ids.md_list.remove_widget(instance)
if dash.number_items_mdlist > 0:
dash.number_items_mdlist -= 1
dash.ids.numero_actividades_dash.text = str(dash.number_items_mdlist)
# MODIFY INDEX SO TO MATCH THE MDLIST INDEX
index = instance.id
dash.minutes_items_mdlist -= int(dash.duracion_actividades_list[0]) # Should replace '0' with 'index'
if int(dash.number_items_mdlist) != 0:
dash.ids.promedio_tiempo_actividades.text = str(round(int(dash.minutes_items_mdlist) /
int(dash.number_items_mdlist)))
else:
dash.ids.promedio_tiempo_actividades.text = '0'
del dash.duracion_actividades_list[0] # Should replace '0' with 'index'
self.show_toast()
def show_toast(self):
toast("Actividad eliminada del cronograma")
# DASHBOARD ################################
class DashboardWindow(Screen):
number_items_mdlist = 0
minutes_items_mdlist = 0
duracion_actividades_list = []
def on_pre_enter(self, *args):
Window.size = (Window.width + 1, Window.height + 1)
Window.size = (Window.width - 1, Window.height - 1)
# ACTIVITIES WINDOW ################################
class IngActivWindow(Screen):
menu = None
def dropdown_activity(self):
# Create the drop down menu
actividades = ["Correo electrónico", "Hora Regreso a Oficina", "Hora Salida de Oficina",
"Llamada de cortesia", "Llamada de Presentación", "Llamada de Promoción",
"Seguimiento a Cotización", "Traslado", "Visita a Cliente", "Whatsapp"]
menu_items = [{"text": f"{actividad}"} for actividad in actividades]
self.menu = MDDropdownMenu(
caller=self.ids.dropdown_Actividades,
items=menu_items,
width_mult=5,
)
self.menu.open()
self.menu.bind(on_release=self.set_item)
def set_item(self, instance_menu, instance_menu_item):
def set_item(interval):
self.ids.dropdown_Actividades.text = instance_menu_item.text
instance_menu.dismiss()
Clock.schedule_once(set_item, 0.5)
def format_hour(self):
if len(self.ids.hour_field.text) > 2:
self.ids.hour_field.text = self.ids.hour_field.text[:-1]
if self.ids.hour_field.text != '' and int(self.ids.hour_field.text) > 12:
self.ids.hour_field.text = self.ids.hour_field.text[:-1]
self.ids.hora_final.text = self.ids.hour_field.text + ':00 ____'
def format_minute(self):
if len(self.ids.minute_field.text) > 2:
self.ids.minute_field.text = self.ids.minute_field.text[:-1]
if self.ids.minute_field.text != '' and int(self.ids.minute_field.text) > 59:
self.ids.minute_field.text = self.ids.minute_field.text[:-1]
self.ids.hora_final.text = self.ids.hour_field.text + ':' + self.ids.minute_field.text + ' ____'
def format_am_pm(self):
if self.ids.toggle_am.state == 'down':
self.ids.hora_final.text = self.ids.hora_final.text[:-5] + ' a.m.'
elif self.ids.toggle_pm.state == 'down':
self.ids.hora_final.text = self.ids.hora_final.text[:-5] + ' p.m.'
def calculate_final_time(self):
if self.ids.hour_field != '' and self.ids.minute_field != '' and self.ids.duracion.text != '':
add_minutes = str(int(self.ids.minute_field.text) + int(self.ids.duracion.text))
# Check if added minutes does not surpass 60
# < 60 --> just add minute_field and duracion
if int(add_minutes) < 60:
self.ids.hora_final.text = self.ids.hour_field.text + ':' + add_minutes
# Add a.m./p.m. to label depending on the toggle button selected
if self.ids.toggle_am.state == 'down':
self.ids.hora_final.text = self.ids.hora_final.text + ' a.m.'
elif self.ids.toggle_pm.state == 'down':
self.ids.hora_final.text = self.ids.hora_final.text + ' p.m.'
# if >= 60 -->
else:
hours_to_add = int(add_minutes) / 60
minutes_to_add = int(add_minutes) % 60
add_hours = int(self.ids.hour_field.text) + int(hours_to_add)
if len(str(minutes_to_add)) == 1:
minutes_to_add = '0' + str(minutes_to_add)
# Si la suma de las horas es mayor a 12, cambiar a formato de 12 horas
if int(add_hours) == 12:
if self.ids.toggle_am.state == 'down':
self.ids.hora_final.text = str(add_hours) + ':' + str(minutes_to_add) + ' p.m.'
elif self.ids.toggle_pm.state == 'down':
self.ids.hora_final.text = str(add_hours) + ':' + str(minutes_to_add) + ' a.m.'
elif int(add_hours) > 11:
if int(self.ids.hour_field.text) == 12:
if self.ids.toggle_am.state == 'down':
add_hours -= 12
self.ids.hora_final.text = str(add_hours) + ':' + str(minutes_to_add) + ' a.m.'
elif self.ids.toggle_pm.state == 'down':
add_hours -= 12
self.ids.hora_final.text = str(add_hours) + ':' + str(minutes_to_add) + ' p.m.'
else:
if self.ids.toggle_am.state == 'down':
add_hours -= 12
self.ids.hora_final.text = str(add_hours) + ':' + str(minutes_to_add) + ' p.m.'
elif self.ids.toggle_pm.state == 'down':
add_hours -= 12
self.ids.hora_final.text = str(add_hours) + ':' + str(minutes_to_add) + ' a.m.'
else:
self.ids.hora_final.text = str(add_hours) + ':' + str(minutes_to_add)
# Add a.m./p.m. to label depending on the toggle button selected
if self.ids.toggle_am.state == 'down':
self.ids.hora_final.text = self.ids.hora_final.text + ' a.m.'
elif self.ids.toggle_pm.state == 'down':
self.ids.hora_final.text = self.ids.hora_final.text + ' p.m.'
if self.ids.duracion.text == '' or self.ids.duracion.text == 0:
self.ids.hora_final.text = str(self.ids.hour_field.text) + ':' + str(self.ids.minute_field.text)
if self.ids.toggle_am.state == 'down':
self.ids.hora_final.text = self.ids.hora_final.text + ' a.m.'
elif self.ids.toggle_pm.state == 'down':
self.ids.hora_final.text = self.ids.hora_final.text + ' p.m.'
def complete_registration(self):
dash = MDApp.get_running_app().root.get_screen('dash')
activity = MDApp.get_running_app().root.get_screen('ingActiv')
if activity.ids.toggle_am.state == 'down':
dash.ids.md_list.add_widget(
SwipeToDeleteItem(text=f"{activity.ids.dropdown_Actividades.text}",
secondary_text=f"{activity.ids.hour_field.text}:{activity.ids.minute_field.text} a.m."
f" - {activity.ids.hora_final.text}"))
elif activity.ids.toggle_pm.state == 'down':
dash.ids.md_list.add_widget(
SwipeToDeleteItem(text=f"{activity.ids.dropdown_Actividades.text}",
secondary_text=f"{activity.ids.hour_field.text}:{activity.ids.minute_field.text} p.m."
f" - {activity.ids.hora_final.text}"))
dash.number_items_mdlist += 1
dash.minutes_items_mdlist += int(activity.ids.duracion.text)
dash.duracion_actividades_list.append(activity.ids.duracion.text)
dash.ids.numero_actividades_dash.text = str(dash.number_items_mdlist)
dash.ids.promedio_tiempo_actividades.text = str(round(int(dash.minutes_items_mdlist) /
int(dash.number_items_mdlist)))
self.show_toast_activities()
def show_toast_activities(self):
toast("Actividad registrada con éxito")
# WINDOW MANAGER ################################
class WindowManager(ScreenManager):
pass
# MAIN CLASS ################################
class ReproducibleExample(MDApp):
enie = 'ñ'
acento_A = 'Á'
acento_a = 'á'
acento_E = 'É'
acento_e = 'é'
acento_I = 'Í'
acento_i = 'í'
acento_O = 'Ó'
acento_o = 'ó'
acento_U = 'Ú'
acento_u = 'ú'
interrog_inic = '¿'
def build(self):
self.theme_cls.primary_palette = "Teal"
return WindowManager()
if __name__ == "__main__":
ReproducibleExample().run()
KV 文件:
<WindowManager>:
id: screen_manager
DashboardWindow:
id: dash
name:'dash'
IngActivWindow:
id: ingActiv
name: 'ingActiv'
<DashboardWindow>:
name: "dash"
BoxLayout:
orientation: 'vertical'
MDCard:
size_hint: (0.75, 0.8)
pos_hint: {'center_x': 0.5, 'center_y': 0.44}
orientation: 'vertical'
padding: '15dp'
spacing: '10dp'
md_bg_color: [1, 1, 1, 0.75]
radius: [16, ]
MDRaisedButton:
text: 'Next Page'
on_release:
root.manager.current = 'ingActiv'
MDLabel:
text: 'Datos de Actividades y Cronograma'
font_style: 'H5'
valign: 'middle'
size_hint: 1, 0.05
MDBoxLayout:
orientation: 'horizontal'
padding: "10dp", 0, "10dp", "10dp"
spacing: "10dp"
size_hint: 1, 0.30
MDCard:
size_hint: 0.9, 0.9
orientation: 'vertical'
padding: '15dp'
spacing: '15dp'
md_bg_color: [0.811, 0, 0.058, 0.7]
radius: [16, ]
MDLabel:
id: promedio_tiempo_actividades
text: "0"
theme_text_color: "Custom"
text_color: 1, 1, 1, 1
font_style: 'H1'
halign: 'center'
font_size: (root.width**2 + root.height**2) / 11**4
MDLabel:
text: "Tiempo promedio de actividades"
theme_text_color: "Custom"
text_color: 1, 1, 1, 1
font_style: 'Subtitle2'
halign: 'center'
MDCard:
size_hint: 0.9, 0.9
orientation: 'vertical'
padding: '15dp'
spacing: '15dp'
md_bg_color: [0.121, .227, 0.576, 0.7]
radius: [16, ]
MDLabel:
id: numero_actividades_dash
text: "0"
theme_text_color: "Custom"
text_color: 1, 1, 1, 1
font_style: 'H1'
halign: 'center'
font_size: (root.width**2 + root.height**2) / 11**4
MDLabel:
text: 'N' + app.acento_u + 'mero de actividades realizadas'
theme_text_color: "Custom"
text_color: 1, 1, 1, 1
font_style: 'Subtitle2'
halign: 'center'
MDBoxLayout:
orientation: 'horizontal'
padding: "10dp", 0, "10dp", "10dp"
spacing: "10dp"
size_hint: 1, 0.65
MDCard:
orientation: 'vertical'
padding: '15dp'
spacing: '10dp'
md_bg_color: [0.419, .725, 0.941, 0.7]
radius: [16, ]
MDBoxLayout:
orientation: 'horizontal'
size_hint_y: 0.15
MDLabel:
text: "Cronograma del dia con Hora de Inicio y Final, Cliente, Actividad, y Resultado"
theme_text_color: "Custom"
text_color: 1, 1, 1, 1
font_style: 'Subtitle2'
halign: 'center'
TooltipMDIconButton:
icon: 'plus'
tooltip_text: 'Agregar actividad'
pos_hint: {"center_x": 0.5, "center_y": 0.5}
font_color: 0,0,0,1
on_press:
root.manager.current = 'ingActiv'
root.manager.transition.direction = 'left'
MDBoxLayout:
orientation: "vertical"
spacing: "10dp"
size_hint_y: 0.85
ScrollView:
scroll_timeout: 100
MDList:
id: md_list
padding: 0
### EXTRAS: SWIPE AND DELETE ITEM ####################
<SwipeToDeleteItem>:
size_hint_y: None
height: content.height
MDCardSwipeLayerBox:
padding: "8dp"
MDIconButton:
icon: "trash-can"
pos_hint: {"center_y": .5}
on_release: root.remove_item(root)
MDCardSwipeFrontBox:
TwoLineListItem:
id: content
text: root.text
secondary_text: root.secondary_text
_no_ripple_effect: True
max_opened_x: "50dp"
<IngActivWindow>:
##################### ACTIVIDADES REALIZADAS ############################################################
<IngActivWindow>:
name: 'ingActiv'
FloatLayout:
cols:1
MDCard:
size_hint: 0.80,0.66
pos_hint: {"center_x": 0.5, "center_y": 0.45}
radius: [36, ]
padding: '10dp'
md_bg_color: [1, 1, 1, 0.85]
ScrollView:
MDGridLayout:
id: widget_container
cols:1
size_hint_y: None
height: self.minimum_height
padding: '15dp', '15dp', '15dp', '15dp'
spacing: '20dp'
adaptive_height: True
MDRaisedButton:
text: 'Next Page'
on_release:
root.manager.current = 'dash'
MDLabel:
id: tiempoActiv
text: "Hora y Tipo de Actividad"
pos_hint: {"center_x":0.5, "center_y": 0.5}
bold: 'True'
font_style: 'Button'
font_size: '18sp'
MDBoxLayout:
orientation: 'horizontal'
padding: "15dp", "10dp", "15dp", "5dp"
spacing: "10dp"
adaptive_height: True
size_hint: 1, None
MDTextField:
id: hour_field
hint_text: 'Hora'
helper_text: 'Max: 12'
helper_text_mode: 'on_focus'
input_filter: 'int'
write_tab: False
pos_hint: {"center_x":0.5, "center_y": 0.5}
size_hint_x: 0.2
on_text: root.format_hour()
MDTextField:
id: minute_field
hint_text: 'Minuto'
helper_text: 'Max: 59'
helper_text_mode: 'on_focus'
input_filter: 'int'
write_tab: False
pos_hint: {"center_x":0.5, "center_y": 0.5}
size_hint_x: 0.2
on_text: root.format_minute()
MyToggleButton:
id: toggle_am
text: "A.M."
group: "hora"
pos_hint: {"center_x":0.5, "center_y": 0.5}
on_press: root.format_am_pm()
MyToggleButton:
id: toggle_pm
text: "P.M."
group: "hora"
pos_hint: {"center_x":0.5, "center_y": 0.5}
on_press: root.format_am_pm()
# DURACIÓN DE ACTIVIDAD
MDBoxLayout:
orientation: 'horizontal'
padding: "15dp", "5dp", "15dp", "15dp"
spacing: "15dp"
adaptive_height: True
size_hint: 1, None
MDTextField:
pos_hint: {"x":0, "center_y": 0.5}
id: duracion
hint_text: 'Duraci' + app.acento_o + 'n de actividad'
helper_text: 'Duracion en minutos'
helper_text_mode: 'on_focus'
write_tab: False
input_filter: 'int'
size_hint_x: 0.45
on_text: root.calculate_final_time()
MDBoxLayout:
orientation: 'horizontal'
size_hint_x: 0.45
spacing: '15dp'
MDLabel:
text: 'Hora de termino:'
font_size: '12sp'
theme_text_color: "Custom"
text_color: 0, 0, 0, 0.50
halign: 'right'
MDLabel:
id: hora_final
text: ''
font_size: '16sp'
theme_text_color: "Custom"
text_color: 0, 0, 0, 0.50
# TIPO DE ACTIVIDAD
MDBoxLayout:
orientation: 'horizontal'
padding: "15dp", "5dp", "15dp", "5dp"
spacing: "5dp"
adaptive_height: True
size_hint: 1, None
MDTextField:
id: dropdown_Actividades
write_tab: False
size_hint: 1, None
pos_hint: {"x": 0, "center_y": 0.5}
icon_right: 'arrow-down-drop-circle-outline'
hint_text: 'Seleccionar Tipo de Actividad'
write_tab: False
valign: 'bottom'
enabled: False
on_focus: if self.focus: root.dropdown_activity()
MDSeparator:
height: "2dp"
MDRaisedButton:
text: "Registrar Actividad"
size_hint: None, None
pos_hint: {'center_x': 0.5, 'center_y': 0.5}
font_size: '19sp'
on_release:
root.complete_registration()
我希望我的解释很清楚。底线,如何获取 MDList 的索引?
非常感谢。
您可以使用 MDList
的 children
列表的 index()
方法获取 MDList
中项目的索引。但是,这将不是 duracion_actividades_list
中相应元素的索引,因为小部件被插入到子列表的开头,并且您正在将值附加到持续时间列表。这是计算正确索引的方法:
index = dash.number_items_mdlist - 1 - dash.ids.md_list.children.index(instance)
可能的简化可能是通过将持续时间插入列表的开头来模仿 add_widget()
行为。或者将持续时间保存在字典中,其中键是 SwipeToDeleteItem
实例。或者只是将持续时间保持为 SwipeToDeleteItem
.
的 属性
我正在尝试构建一个在 Python 和 KivyMD 中具有计划管理器的应用程序。代码的第一页是显示日程表的地方,另一页是您将添加信息的地方。在第二页填写表格后,仪表板 window 将更新,注册的 activity 信息将添加到 MDList 小部件中。左上MDCard保存活动的平均时间,右上MDCard保存活动注册数量。
如果 he/she 在注册时出错(向右滑动 MDList 项目并单击垃圾桶图标),用户将有机会删除以前注册的 activity。当然,删除后需要更新小部件值。我的问题是在尝试更新活动的平均时间时出现的:要计算所有金额保存到列表中的平均值,我想做的是获取 MDList 中删除的项目的索引。所以我可以相应地删除金额并进行准确的计算。 (其实我只是选择了要删除的索引为0,所以删除的项永远是列表中的第一项。
Python 文件:
from kivymd.app import MDApp
from kivy.uix.screenmanager import ScreenManager, Screen
from kivymd.toast import toast
from kivymd.uix.menu import MDDropdownMenu
from kivy.clock import Clock
from kivy.config import Config
from kivy.core.window import Window
from kivy.utils import platform
from kivy.properties import StringProperty
from kivymd.uix.card import MDCardSwipe
from kivymd.uix.button import MDIconButton, MDTooltip
from kivymd.uix.behaviors.toggle_behavior import MDToggleButton
from kivymd.uix.button import MDRectangleFlatButton
if platform not in ('android', 'ios'):
Config.set('graphics', 'resizable', '0')
Window.size = (600, 700)
class TooltipMDIconButton(MDIconButton, MDTooltip):
pass
class MyToggleButton(MDRectangleFlatButton, MDToggleButton):
def __init__(self, **kwargs):
super().__init__(**kwargs)
self.background_down = self.theme_cls.primary_light
class SwipeToDeleteItem(MDCardSwipe):
text = StringProperty()
secondary_text = StringProperty()
def remove_item(self, instance):
dash = MDApp.get_running_app().root.get_screen('dash')
dash.ids.md_list.remove_widget(instance)
if dash.number_items_mdlist > 0:
dash.number_items_mdlist -= 1
dash.ids.numero_actividades_dash.text = str(dash.number_items_mdlist)
# MODIFY INDEX SO TO MATCH THE MDLIST INDEX
index = instance.id
dash.minutes_items_mdlist -= int(dash.duracion_actividades_list[0]) # Should replace '0' with 'index'
if int(dash.number_items_mdlist) != 0:
dash.ids.promedio_tiempo_actividades.text = str(round(int(dash.minutes_items_mdlist) /
int(dash.number_items_mdlist)))
else:
dash.ids.promedio_tiempo_actividades.text = '0'
del dash.duracion_actividades_list[0] # Should replace '0' with 'index'
self.show_toast()
def show_toast(self):
toast("Actividad eliminada del cronograma")
# DASHBOARD ################################
class DashboardWindow(Screen):
number_items_mdlist = 0
minutes_items_mdlist = 0
duracion_actividades_list = []
def on_pre_enter(self, *args):
Window.size = (Window.width + 1, Window.height + 1)
Window.size = (Window.width - 1, Window.height - 1)
# ACTIVITIES WINDOW ################################
class IngActivWindow(Screen):
menu = None
def dropdown_activity(self):
# Create the drop down menu
actividades = ["Correo electrónico", "Hora Regreso a Oficina", "Hora Salida de Oficina",
"Llamada de cortesia", "Llamada de Presentación", "Llamada de Promoción",
"Seguimiento a Cotización", "Traslado", "Visita a Cliente", "Whatsapp"]
menu_items = [{"text": f"{actividad}"} for actividad in actividades]
self.menu = MDDropdownMenu(
caller=self.ids.dropdown_Actividades,
items=menu_items,
width_mult=5,
)
self.menu.open()
self.menu.bind(on_release=self.set_item)
def set_item(self, instance_menu, instance_menu_item):
def set_item(interval):
self.ids.dropdown_Actividades.text = instance_menu_item.text
instance_menu.dismiss()
Clock.schedule_once(set_item, 0.5)
def format_hour(self):
if len(self.ids.hour_field.text) > 2:
self.ids.hour_field.text = self.ids.hour_field.text[:-1]
if self.ids.hour_field.text != '' and int(self.ids.hour_field.text) > 12:
self.ids.hour_field.text = self.ids.hour_field.text[:-1]
self.ids.hora_final.text = self.ids.hour_field.text + ':00 ____'
def format_minute(self):
if len(self.ids.minute_field.text) > 2:
self.ids.minute_field.text = self.ids.minute_field.text[:-1]
if self.ids.minute_field.text != '' and int(self.ids.minute_field.text) > 59:
self.ids.minute_field.text = self.ids.minute_field.text[:-1]
self.ids.hora_final.text = self.ids.hour_field.text + ':' + self.ids.minute_field.text + ' ____'
def format_am_pm(self):
if self.ids.toggle_am.state == 'down':
self.ids.hora_final.text = self.ids.hora_final.text[:-5] + ' a.m.'
elif self.ids.toggle_pm.state == 'down':
self.ids.hora_final.text = self.ids.hora_final.text[:-5] + ' p.m.'
def calculate_final_time(self):
if self.ids.hour_field != '' and self.ids.minute_field != '' and self.ids.duracion.text != '':
add_minutes = str(int(self.ids.minute_field.text) + int(self.ids.duracion.text))
# Check if added minutes does not surpass 60
# < 60 --> just add minute_field and duracion
if int(add_minutes) < 60:
self.ids.hora_final.text = self.ids.hour_field.text + ':' + add_minutes
# Add a.m./p.m. to label depending on the toggle button selected
if self.ids.toggle_am.state == 'down':
self.ids.hora_final.text = self.ids.hora_final.text + ' a.m.'
elif self.ids.toggle_pm.state == 'down':
self.ids.hora_final.text = self.ids.hora_final.text + ' p.m.'
# if >= 60 -->
else:
hours_to_add = int(add_minutes) / 60
minutes_to_add = int(add_minutes) % 60
add_hours = int(self.ids.hour_field.text) + int(hours_to_add)
if len(str(minutes_to_add)) == 1:
minutes_to_add = '0' + str(minutes_to_add)
# Si la suma de las horas es mayor a 12, cambiar a formato de 12 horas
if int(add_hours) == 12:
if self.ids.toggle_am.state == 'down':
self.ids.hora_final.text = str(add_hours) + ':' + str(minutes_to_add) + ' p.m.'
elif self.ids.toggle_pm.state == 'down':
self.ids.hora_final.text = str(add_hours) + ':' + str(minutes_to_add) + ' a.m.'
elif int(add_hours) > 11:
if int(self.ids.hour_field.text) == 12:
if self.ids.toggle_am.state == 'down':
add_hours -= 12
self.ids.hora_final.text = str(add_hours) + ':' + str(minutes_to_add) + ' a.m.'
elif self.ids.toggle_pm.state == 'down':
add_hours -= 12
self.ids.hora_final.text = str(add_hours) + ':' + str(minutes_to_add) + ' p.m.'
else:
if self.ids.toggle_am.state == 'down':
add_hours -= 12
self.ids.hora_final.text = str(add_hours) + ':' + str(minutes_to_add) + ' p.m.'
elif self.ids.toggle_pm.state == 'down':
add_hours -= 12
self.ids.hora_final.text = str(add_hours) + ':' + str(minutes_to_add) + ' a.m.'
else:
self.ids.hora_final.text = str(add_hours) + ':' + str(minutes_to_add)
# Add a.m./p.m. to label depending on the toggle button selected
if self.ids.toggle_am.state == 'down':
self.ids.hora_final.text = self.ids.hora_final.text + ' a.m.'
elif self.ids.toggle_pm.state == 'down':
self.ids.hora_final.text = self.ids.hora_final.text + ' p.m.'
if self.ids.duracion.text == '' or self.ids.duracion.text == 0:
self.ids.hora_final.text = str(self.ids.hour_field.text) + ':' + str(self.ids.minute_field.text)
if self.ids.toggle_am.state == 'down':
self.ids.hora_final.text = self.ids.hora_final.text + ' a.m.'
elif self.ids.toggle_pm.state == 'down':
self.ids.hora_final.text = self.ids.hora_final.text + ' p.m.'
def complete_registration(self):
dash = MDApp.get_running_app().root.get_screen('dash')
activity = MDApp.get_running_app().root.get_screen('ingActiv')
if activity.ids.toggle_am.state == 'down':
dash.ids.md_list.add_widget(
SwipeToDeleteItem(text=f"{activity.ids.dropdown_Actividades.text}",
secondary_text=f"{activity.ids.hour_field.text}:{activity.ids.minute_field.text} a.m."
f" - {activity.ids.hora_final.text}"))
elif activity.ids.toggle_pm.state == 'down':
dash.ids.md_list.add_widget(
SwipeToDeleteItem(text=f"{activity.ids.dropdown_Actividades.text}",
secondary_text=f"{activity.ids.hour_field.text}:{activity.ids.minute_field.text} p.m."
f" - {activity.ids.hora_final.text}"))
dash.number_items_mdlist += 1
dash.minutes_items_mdlist += int(activity.ids.duracion.text)
dash.duracion_actividades_list.append(activity.ids.duracion.text)
dash.ids.numero_actividades_dash.text = str(dash.number_items_mdlist)
dash.ids.promedio_tiempo_actividades.text = str(round(int(dash.minutes_items_mdlist) /
int(dash.number_items_mdlist)))
self.show_toast_activities()
def show_toast_activities(self):
toast("Actividad registrada con éxito")
# WINDOW MANAGER ################################
class WindowManager(ScreenManager):
pass
# MAIN CLASS ################################
class ReproducibleExample(MDApp):
enie = 'ñ'
acento_A = 'Á'
acento_a = 'á'
acento_E = 'É'
acento_e = 'é'
acento_I = 'Í'
acento_i = 'í'
acento_O = 'Ó'
acento_o = 'ó'
acento_U = 'Ú'
acento_u = 'ú'
interrog_inic = '¿'
def build(self):
self.theme_cls.primary_palette = "Teal"
return WindowManager()
if __name__ == "__main__":
ReproducibleExample().run()
KV 文件:
<WindowManager>:
id: screen_manager
DashboardWindow:
id: dash
name:'dash'
IngActivWindow:
id: ingActiv
name: 'ingActiv'
<DashboardWindow>:
name: "dash"
BoxLayout:
orientation: 'vertical'
MDCard:
size_hint: (0.75, 0.8)
pos_hint: {'center_x': 0.5, 'center_y': 0.44}
orientation: 'vertical'
padding: '15dp'
spacing: '10dp'
md_bg_color: [1, 1, 1, 0.75]
radius: [16, ]
MDRaisedButton:
text: 'Next Page'
on_release:
root.manager.current = 'ingActiv'
MDLabel:
text: 'Datos de Actividades y Cronograma'
font_style: 'H5'
valign: 'middle'
size_hint: 1, 0.05
MDBoxLayout:
orientation: 'horizontal'
padding: "10dp", 0, "10dp", "10dp"
spacing: "10dp"
size_hint: 1, 0.30
MDCard:
size_hint: 0.9, 0.9
orientation: 'vertical'
padding: '15dp'
spacing: '15dp'
md_bg_color: [0.811, 0, 0.058, 0.7]
radius: [16, ]
MDLabel:
id: promedio_tiempo_actividades
text: "0"
theme_text_color: "Custom"
text_color: 1, 1, 1, 1
font_style: 'H1'
halign: 'center'
font_size: (root.width**2 + root.height**2) / 11**4
MDLabel:
text: "Tiempo promedio de actividades"
theme_text_color: "Custom"
text_color: 1, 1, 1, 1
font_style: 'Subtitle2'
halign: 'center'
MDCard:
size_hint: 0.9, 0.9
orientation: 'vertical'
padding: '15dp'
spacing: '15dp'
md_bg_color: [0.121, .227, 0.576, 0.7]
radius: [16, ]
MDLabel:
id: numero_actividades_dash
text: "0"
theme_text_color: "Custom"
text_color: 1, 1, 1, 1
font_style: 'H1'
halign: 'center'
font_size: (root.width**2 + root.height**2) / 11**4
MDLabel:
text: 'N' + app.acento_u + 'mero de actividades realizadas'
theme_text_color: "Custom"
text_color: 1, 1, 1, 1
font_style: 'Subtitle2'
halign: 'center'
MDBoxLayout:
orientation: 'horizontal'
padding: "10dp", 0, "10dp", "10dp"
spacing: "10dp"
size_hint: 1, 0.65
MDCard:
orientation: 'vertical'
padding: '15dp'
spacing: '10dp'
md_bg_color: [0.419, .725, 0.941, 0.7]
radius: [16, ]
MDBoxLayout:
orientation: 'horizontal'
size_hint_y: 0.15
MDLabel:
text: "Cronograma del dia con Hora de Inicio y Final, Cliente, Actividad, y Resultado"
theme_text_color: "Custom"
text_color: 1, 1, 1, 1
font_style: 'Subtitle2'
halign: 'center'
TooltipMDIconButton:
icon: 'plus'
tooltip_text: 'Agregar actividad'
pos_hint: {"center_x": 0.5, "center_y": 0.5}
font_color: 0,0,0,1
on_press:
root.manager.current = 'ingActiv'
root.manager.transition.direction = 'left'
MDBoxLayout:
orientation: "vertical"
spacing: "10dp"
size_hint_y: 0.85
ScrollView:
scroll_timeout: 100
MDList:
id: md_list
padding: 0
### EXTRAS: SWIPE AND DELETE ITEM ####################
<SwipeToDeleteItem>:
size_hint_y: None
height: content.height
MDCardSwipeLayerBox:
padding: "8dp"
MDIconButton:
icon: "trash-can"
pos_hint: {"center_y": .5}
on_release: root.remove_item(root)
MDCardSwipeFrontBox:
TwoLineListItem:
id: content
text: root.text
secondary_text: root.secondary_text
_no_ripple_effect: True
max_opened_x: "50dp"
<IngActivWindow>:
##################### ACTIVIDADES REALIZADAS ############################################################
<IngActivWindow>:
name: 'ingActiv'
FloatLayout:
cols:1
MDCard:
size_hint: 0.80,0.66
pos_hint: {"center_x": 0.5, "center_y": 0.45}
radius: [36, ]
padding: '10dp'
md_bg_color: [1, 1, 1, 0.85]
ScrollView:
MDGridLayout:
id: widget_container
cols:1
size_hint_y: None
height: self.minimum_height
padding: '15dp', '15dp', '15dp', '15dp'
spacing: '20dp'
adaptive_height: True
MDRaisedButton:
text: 'Next Page'
on_release:
root.manager.current = 'dash'
MDLabel:
id: tiempoActiv
text: "Hora y Tipo de Actividad"
pos_hint: {"center_x":0.5, "center_y": 0.5}
bold: 'True'
font_style: 'Button'
font_size: '18sp'
MDBoxLayout:
orientation: 'horizontal'
padding: "15dp", "10dp", "15dp", "5dp"
spacing: "10dp"
adaptive_height: True
size_hint: 1, None
MDTextField:
id: hour_field
hint_text: 'Hora'
helper_text: 'Max: 12'
helper_text_mode: 'on_focus'
input_filter: 'int'
write_tab: False
pos_hint: {"center_x":0.5, "center_y": 0.5}
size_hint_x: 0.2
on_text: root.format_hour()
MDTextField:
id: minute_field
hint_text: 'Minuto'
helper_text: 'Max: 59'
helper_text_mode: 'on_focus'
input_filter: 'int'
write_tab: False
pos_hint: {"center_x":0.5, "center_y": 0.5}
size_hint_x: 0.2
on_text: root.format_minute()
MyToggleButton:
id: toggle_am
text: "A.M."
group: "hora"
pos_hint: {"center_x":0.5, "center_y": 0.5}
on_press: root.format_am_pm()
MyToggleButton:
id: toggle_pm
text: "P.M."
group: "hora"
pos_hint: {"center_x":0.5, "center_y": 0.5}
on_press: root.format_am_pm()
# DURACIÓN DE ACTIVIDAD
MDBoxLayout:
orientation: 'horizontal'
padding: "15dp", "5dp", "15dp", "15dp"
spacing: "15dp"
adaptive_height: True
size_hint: 1, None
MDTextField:
pos_hint: {"x":0, "center_y": 0.5}
id: duracion
hint_text: 'Duraci' + app.acento_o + 'n de actividad'
helper_text: 'Duracion en minutos'
helper_text_mode: 'on_focus'
write_tab: False
input_filter: 'int'
size_hint_x: 0.45
on_text: root.calculate_final_time()
MDBoxLayout:
orientation: 'horizontal'
size_hint_x: 0.45
spacing: '15dp'
MDLabel:
text: 'Hora de termino:'
font_size: '12sp'
theme_text_color: "Custom"
text_color: 0, 0, 0, 0.50
halign: 'right'
MDLabel:
id: hora_final
text: ''
font_size: '16sp'
theme_text_color: "Custom"
text_color: 0, 0, 0, 0.50
# TIPO DE ACTIVIDAD
MDBoxLayout:
orientation: 'horizontal'
padding: "15dp", "5dp", "15dp", "5dp"
spacing: "5dp"
adaptive_height: True
size_hint: 1, None
MDTextField:
id: dropdown_Actividades
write_tab: False
size_hint: 1, None
pos_hint: {"x": 0, "center_y": 0.5}
icon_right: 'arrow-down-drop-circle-outline'
hint_text: 'Seleccionar Tipo de Actividad'
write_tab: False
valign: 'bottom'
enabled: False
on_focus: if self.focus: root.dropdown_activity()
MDSeparator:
height: "2dp"
MDRaisedButton:
text: "Registrar Actividad"
size_hint: None, None
pos_hint: {'center_x': 0.5, 'center_y': 0.5}
font_size: '19sp'
on_release:
root.complete_registration()
我希望我的解释很清楚。底线,如何获取 MDList 的索引?
非常感谢。
您可以使用 MDList
的 children
列表的 index()
方法获取 MDList
中项目的索引。但是,这将不是 duracion_actividades_list
中相应元素的索引,因为小部件被插入到子列表的开头,并且您正在将值附加到持续时间列表。这是计算正确索引的方法:
index = dash.number_items_mdlist - 1 - dash.ids.md_list.children.index(instance)
可能的简化可能是通过将持续时间插入列表的开头来模仿 add_widget()
行为。或者将持续时间保存在字典中,其中键是 SwipeToDeleteItem
实例。或者只是将持续时间保持为 SwipeToDeleteItem
.