I created my own widget class and assigned a default background to it, in the python file, several are created in the loop, but the background image is only visible on the last one created, why is this happening? Here is the code:
Here is the working (incorrect) code I got from my application:
from kivy.app import App
from kivy.lang import Builder
from kivy.uix.floatlayout import FloatLayout
from kivy.uix.label import Label
from kivymd.app import MDApp
import own_classes
KV = ("""
<NewFloatLayout>
FloatLayout:
canvas.before:
Rectangle:
pos: self.pos
size: self.size
source: 'icons/events/event_back_panel.png'
""")
class NewFloatLayout(FloatLayout):
pass
def __init__(self, **kwargs):
super(NewFloatLayout, self).__init__(**kwargs)
class TestApp(MDApp):
def build(self):
self.theme_cls.theme_style = 'Light'
self.theme_cls.primary_palette = 'BlueGray'
Builder.load_file("test.kv")
Builder.load_string(KV)
def on_start(self):
events_filling()
def pass_funk():
pass
# заполняет экран эвентов
def events_filling():
app = App.get_running_app()
events_dict = [{'date': '2023-02-25', 'date_time': '2023-02-25 05:20:00', 'description': 'pat cat', 'status':
'active', 'time': '05:20:00', 'title': 'pat', 'event_key': '-NP3v5nCWQO-VsastQdA'},
{'date': '2023-03-18', 'date_time': '2023-03-18 00:29:00', 'description': 'drink beer', 'status': 'active', 'time':
'00:29:00', 'title': 'drink beer', 'event_key': '-NQig0z4yKmHs0o2bSe-'},
{'date': '2023-04-23', 'date_time': '2023-04-23 15:20:00', 'description': 'eat meat', 'status': 'active', 'time':
'15:20:00', 'title': 'eat meat', 'event_key': '-NP6a-RDO0nKwH794j_F'}]
for i in events_dict:
layout_for_event = NewFloatLayout()
events_box_layout = app.root.ids['events_layout']
title = own_classes.LabelButton(text=i['title'], size_hint=(.7, .3),
pos_hint={"top": .95, "right": .8}, color=(.72, .39, 0, 1), halign="left", valign="top",
font_size=16)
title.bind(size=title.setter('text_size'), on_release=pass_funk)
description = own_classes.LabelButton(text=i['description'], size_hint=(.7, .4),
pos_hint={"top": .65, "right": .8}, halign="left", valign="top", font_size=15)
description.bind(size=description.setter('text_size'), on_release=pass_funk)
date = Label(text=i['date'], size_hint=(.4, .3), color=(.6, .6, .6, 1),
pos_hint={"top": .3, "left": .5})
time = Label(text=i['time'], size_hint=(.4, .3), color=(.6, .6, .6, 1),
pos_hint={"top": .3, "right": .8})
copy_button = own_classes.ImageButton(source="icons/events/copy.png", size_hint=(.25, .3),
pos_hint={"top": .95, "right": 1})
copy_button.bind(on_release=pass_funk)
done_button = own_classes.ImageButton(source="icons/events/done.png", size_hint=(.25, .3),
pos_hint={"top": .65, "right": 1})
done_button.bind(on_release=pass_funk)
delete_button = own_classes.ImageButton(source="icons/events/delete.png", size_hint=(.25, .3),
pos_hint={"top": .35, "right": 1})
delete_button.bind(on_release=pass_funk)
layout_for_event.add_widget(title)
layout_for_event.add_widget(description)
layout_for_event.add_widget(date)
layout_for_event.add_widget(time)
layout_for_event.add_widget(copy_button)
layout_for_event.add_widget(done_button)
layout_for_event.add_widget(delete_button)
events_box_layout.add_widget(layout_for_event)
TestApp().run()
Here is the kv file:
#:import test test
ScrollView:
pos_hint: {"top": .79, "left": 1}
size_hint: 1, .79
GridLayout:
id: events_layout
name: "events_layout"
cols: 1
size_hint_y: None
pos_hint: {"top": 1, "left": .8}
height: self.minimum_height
row_default_height: '100dp'
row_fource_default: True
In your KV
, you are defining NewFloatLayout
as a FloatLayout
that contains another FloatLayout
. If it is not your intent to have a FloatLayout
inside another FloatLayout
, you can simply remove the extra FloatLayout
, like this:
KV = ("""
<NewFloatLayout>
canvas.before:
Rectangle:
pos: self.pos
size: self.size
source: 'icons/events/event_back_panel.png'
""")
If you do intend to have one FloatLayout
inside another FloatLayout
, then you just need to set the pos
of the inside FloatLayout
, like this:
KV = ("""
<NewFloatLayout>
FloatLayout:
pos: root.pos
canvas.before:
Rectangle:
pos: self.pos
size: self.size
source: 'icons/events/event_back_panel.png'
""")
Otherwise, the inside FloatLayout
gets the default pos
of (0, 0)
, and all three will be at the same position. Also note that the loop that adds widgets to the layout_for_event
is adding widgets to the outside FloatLayout
, not the second (or inside) FloatLayout
, so the indside FloatLayout
is essentially unused.