How to import and instantiate (with keyword arguments) custom made class of Python KivyMD?
Question:
I am trying to learn KivyMD and Python. So, I am fairly new to KivyMD. I have made something like a card (like MDCard) in kivyMD. I am trying to import it to my other application and instanciate it with some arguments. But I am unable to do so. Here is what my code looks like for now.
Filename – finaltile.py
from kivymd.uix.boxlayout import MDBoxLayout
from kivy.properties import StringProperty, ListProperty, ColorProperty
class MyTileItem(MDBoxLayout):
def __init__(self, **kwargs):
super().__init__(**kwargs)
self.box_color = ListProperty()
self.heading_name = StringProperty()
self.heading_color = ColorProperty('#d31010')
self.sub_heading_1 = StringProperty()
self.sub_heading_2 = StringProperty()
self.sub_heading_color = ColorProperty('#d31010')
self.time_duration = StringProperty()
self.time_duration_color = ColorProperty('#d31010')
And its .kv file looks like this:
Filename – finaltile.kv
Both the file is in the same directory.
<MyTileItem>:
orientation: "vertical"
MDBoxLayout:
padding: (sp(10), sp(6), sp(10), sp(10))
# opacity: .5
size_hint:1, None
height: sp(100)
canvas.before:
Color:
rgba: root.box_color
RoundedRectangle:
pos: self.pos
size: self.size
radius: [sp(20), sp(20), sp(20), sp(20)]
MDGridLayout:
rows: 2
spacing: sp(5)
MDLabel:
text: "This is a heading"
halign: 'left'
# valign: 'center'
font_size: sp(18)
color: root.heading_color
bold: True
MDBoxLayout:
MDBoxLayout:
size_hint_x: .6
orientation: 'vertical'
MDLabel:
text: root.sub_heading_1
font_size: sp(15)
color: root.sub_heading_color
bold: True
halign: 'left'
MDLabel:
text: root.sub_heading_2
halign: 'left'
font_size: sp(15)
color: root.sub_heading_color
bold: True
MDLabel:
size_hint_x: .4
text: str(root.time_duration)
color: root.time_duration_color
halign: 'right'
font_size: sp(25)
bold: True
Widget:
Now, I want to do this in some other python file:
from finaltile import MyTileItem
# The Class I want to import and instantiate with available data (like box_color, heading_name, sub_heading_1, sub_heading_2, sub_heading_color, time_duration_color)
from kivymd.app import MDApp
from kivymd.uix.scrollview import ScrollView
from kivy.lang import Builder
from kivymd.uix.boxlayout import MDBoxLayout
from kivymd.uix.gridlayout import MDGridLayout
class MyTile(MDBoxLayout):
pass
class NewTileItem(MyTileItem):
pass
class TestApp(MDApp):
def build(self):
self.theme_cls.primary_palette = "BlueGray"
self.theme_cls.primary_hue = '800'
self.theme_cls.theme_style = "Dark"
self.myview = MyTile()
self.myItem = NewTileItem(box_color = (1, 1, 1, 0.5), heading_name = "This is heading 1.", heading_color = (1, 0, 0, 1), sub_heading_1 = "This is the sub heading 1", sub_heading_2 = "This is sub heading 2", sub_heading_color = (0, 1, 0, 1), time_duration = "01:02:03", time_duration_color = (0, 0, 1, 1))
self.myview.add_widget(self.myItem)
self.myItem = NewTileItem(box_color = (1, 1, 1, 0.5), heading_name = "This is heading 2.", heading_color = (1, 0, 0, 1), sub_heading_1 = "This is the sub heading 1", sub_heading_2 = "This is sub heading 2", sub_heading_color = (0, 1, 0, 1), time_duration = "01:02:03", time_duration_color = (0, 0, 1, 1))
self.myview.add_widget(self.myItem)
return self.myview
if __name__ == '__main__':
TestApp().run()
And the ‘test.kv’ file looks something like this:
#:import MyTileItem finaltile.MyTileItem
<MyTile>:
orientation: 'vertical'
size_hint: 1, None
ScrollView:
MDBoxLayout:
id: box
orientation: 'vertical'
spacing: sp(110)
padding: sp(20), sp(200)
size_hint_y: None
height: self.minimum_height
NewTileItem:
NewTileItem:
NewTileItem:
NewTileItem:
NewTileItem:
NewTileItem:
I want to be able to import the ‘MyTileItem’ class and use it multiple times in different projects. How can I do this? I have searched everywhere and nothing seems to do it for me. Here is an image of what I am trying to achieve.
The Error/Issues I am currently getting is this:
- First, I have a blank screen, which when I try to close, gives me the actual screen I am trying to achieve. (I have no idea why that is happening.
- And then I am getting this the under-written error multiple times when I close the window.
- And I would like to point again that the window closes when I close it twice. First, I get a blank screen, try to close it, which then gives me the actual window. And then when I close it. The window closes and the under-written error pops up like 100 times in a go. The error is:
Traceback (most recent call last):
File "kivygraphicsshader.pyx", line 245, in kivy.graphics.shader.Shader.set_uniform
File "kivygraphicsshader.pyx", line 284, in kivy.graphics.shader.Shader.upload_uniform
IndexError: list index out of range
Exception ignored in: 'kivy.graphics.instructions.RenderContext.set_state'
Traceback (most recent call last):
File "kivygraphicsshader.pyx", line 245, in kivy.graphics.shader.Shader.set_uniform
File "kivygraphicsshader.pyx", line 284, in kivy.graphics.shader.Shader.upload_uniform
IndexError: list index out of range
Answers:
The errors you are getting are caused by not defining the default value for box_color
in your MyTileItem
class. That results in the NewTileItem
widgets that are created by the test.kv
file having a box_color
of []
.
The fix is to modify the finaltile.py
class, something like this:
from kivy.lang import Builder
from kivymd.uix.boxlayout import MDBoxLayout
from kivy.properties import StringProperty, ListProperty, ColorProperty
Builder.load_file('finaltile.kv')
class MyTileItem(MDBoxLayout):
box_color = ListProperty((1, 1, 0, 0.5))
heading_name = StringProperty()
heading_color = ColorProperty('#d31010')
sub_heading_1 = StringProperty()
sub_heading_2 = StringProperty()
sub_heading_color = ColorProperty('#d31010')
time_duration = StringProperty()
time_duration_color = ColorProperty('#d31010')
# def __init__(self, **kwargs):
# super().__init__(**kwargs)
Note that the Properties
must be defined in the class, but outside of any method. Also, I added a call to load the finaltile.kv
file.
Also, in the text.kv
file, the line:
size_hint: 1, None
should be removed.
I am trying to learn KivyMD and Python. So, I am fairly new to KivyMD. I have made something like a card (like MDCard) in kivyMD. I am trying to import it to my other application and instanciate it with some arguments. But I am unable to do so. Here is what my code looks like for now.
Filename – finaltile.py
from kivymd.uix.boxlayout import MDBoxLayout
from kivy.properties import StringProperty, ListProperty, ColorProperty
class MyTileItem(MDBoxLayout):
def __init__(self, **kwargs):
super().__init__(**kwargs)
self.box_color = ListProperty()
self.heading_name = StringProperty()
self.heading_color = ColorProperty('#d31010')
self.sub_heading_1 = StringProperty()
self.sub_heading_2 = StringProperty()
self.sub_heading_color = ColorProperty('#d31010')
self.time_duration = StringProperty()
self.time_duration_color = ColorProperty('#d31010')
And its .kv file looks like this:
Filename – finaltile.kv
Both the file is in the same directory.
<MyTileItem>:
orientation: "vertical"
MDBoxLayout:
padding: (sp(10), sp(6), sp(10), sp(10))
# opacity: .5
size_hint:1, None
height: sp(100)
canvas.before:
Color:
rgba: root.box_color
RoundedRectangle:
pos: self.pos
size: self.size
radius: [sp(20), sp(20), sp(20), sp(20)]
MDGridLayout:
rows: 2
spacing: sp(5)
MDLabel:
text: "This is a heading"
halign: 'left'
# valign: 'center'
font_size: sp(18)
color: root.heading_color
bold: True
MDBoxLayout:
MDBoxLayout:
size_hint_x: .6
orientation: 'vertical'
MDLabel:
text: root.sub_heading_1
font_size: sp(15)
color: root.sub_heading_color
bold: True
halign: 'left'
MDLabel:
text: root.sub_heading_2
halign: 'left'
font_size: sp(15)
color: root.sub_heading_color
bold: True
MDLabel:
size_hint_x: .4
text: str(root.time_duration)
color: root.time_duration_color
halign: 'right'
font_size: sp(25)
bold: True
Widget:
Now, I want to do this in some other python file:
from finaltile import MyTileItem
# The Class I want to import and instantiate with available data (like box_color, heading_name, sub_heading_1, sub_heading_2, sub_heading_color, time_duration_color)
from kivymd.app import MDApp
from kivymd.uix.scrollview import ScrollView
from kivy.lang import Builder
from kivymd.uix.boxlayout import MDBoxLayout
from kivymd.uix.gridlayout import MDGridLayout
class MyTile(MDBoxLayout):
pass
class NewTileItem(MyTileItem):
pass
class TestApp(MDApp):
def build(self):
self.theme_cls.primary_palette = "BlueGray"
self.theme_cls.primary_hue = '800'
self.theme_cls.theme_style = "Dark"
self.myview = MyTile()
self.myItem = NewTileItem(box_color = (1, 1, 1, 0.5), heading_name = "This is heading 1.", heading_color = (1, 0, 0, 1), sub_heading_1 = "This is the sub heading 1", sub_heading_2 = "This is sub heading 2", sub_heading_color = (0, 1, 0, 1), time_duration = "01:02:03", time_duration_color = (0, 0, 1, 1))
self.myview.add_widget(self.myItem)
self.myItem = NewTileItem(box_color = (1, 1, 1, 0.5), heading_name = "This is heading 2.", heading_color = (1, 0, 0, 1), sub_heading_1 = "This is the sub heading 1", sub_heading_2 = "This is sub heading 2", sub_heading_color = (0, 1, 0, 1), time_duration = "01:02:03", time_duration_color = (0, 0, 1, 1))
self.myview.add_widget(self.myItem)
return self.myview
if __name__ == '__main__':
TestApp().run()
And the ‘test.kv’ file looks something like this:
#:import MyTileItem finaltile.MyTileItem
<MyTile>:
orientation: 'vertical'
size_hint: 1, None
ScrollView:
MDBoxLayout:
id: box
orientation: 'vertical'
spacing: sp(110)
padding: sp(20), sp(200)
size_hint_y: None
height: self.minimum_height
NewTileItem:
NewTileItem:
NewTileItem:
NewTileItem:
NewTileItem:
NewTileItem:
I want to be able to import the ‘MyTileItem’ class and use it multiple times in different projects. How can I do this? I have searched everywhere and nothing seems to do it for me. Here is an image of what I am trying to achieve.
The Error/Issues I am currently getting is this:
- First, I have a blank screen, which when I try to close, gives me the actual screen I am trying to achieve. (I have no idea why that is happening.
- And then I am getting this the under-written error multiple times when I close the window.
- And I would like to point again that the window closes when I close it twice. First, I get a blank screen, try to close it, which then gives me the actual window. And then when I close it. The window closes and the under-written error pops up like 100 times in a go. The error is:
Traceback (most recent call last): File "kivygraphicsshader.pyx", line 245, in kivy.graphics.shader.Shader.set_uniform File "kivygraphicsshader.pyx", line 284, in kivy.graphics.shader.Shader.upload_uniform IndexError: list index out of range Exception ignored in: 'kivy.graphics.instructions.RenderContext.set_state' Traceback (most recent call last): File "kivygraphicsshader.pyx", line 245, in kivy.graphics.shader.Shader.set_uniform File "kivygraphicsshader.pyx", line 284, in kivy.graphics.shader.Shader.upload_uniform IndexError: list index out of range
The errors you are getting are caused by not defining the default value for box_color
in your MyTileItem
class. That results in the NewTileItem
widgets that are created by the test.kv
file having a box_color
of []
.
The fix is to modify the finaltile.py
class, something like this:
from kivy.lang import Builder
from kivymd.uix.boxlayout import MDBoxLayout
from kivy.properties import StringProperty, ListProperty, ColorProperty
Builder.load_file('finaltile.kv')
class MyTileItem(MDBoxLayout):
box_color = ListProperty((1, 1, 0, 0.5))
heading_name = StringProperty()
heading_color = ColorProperty('#d31010')
sub_heading_1 = StringProperty()
sub_heading_2 = StringProperty()
sub_heading_color = ColorProperty('#d31010')
time_duration = StringProperty()
time_duration_color = ColorProperty('#d31010')
# def __init__(self, **kwargs):
# super().__init__(**kwargs)
Note that the Properties
must be defined in the class, but outside of any method. Also, I added a call to load the finaltile.kv
file.
Also, in the text.kv
file, the line:
size_hint: 1, None
should be removed.