4

I have a widget(W2), made of other widgets (W1). Each has a corresponding .kv file as below. Running main.py, I expect to see a black background with two labels, vertically stacked. Instead, I get both labels on top of each other, so something has gone wrong.

kivy.factory.FactoryException: Unknown class <W1>

So I thought, "Maybe I should import w1.py in w2.py even though it's not explicitly used in the py file? That ... sort of worked. I get both labels on top of each other, as in the following image.

enter image description here

What am I doing wrong? What is the correct way to write a widget that is expected to be imported/included by another widget? And the correct way to import it?

I tried using Builder.load_file() in the .py file and just importing the .py file but that had similar results.

w1.py:

import kivy
from kivy.properties import StringProperty
from kivy.uix.widget import Widget
kivy.require('1.10.0')

class W1(Widget):
    text = StringProperty('default')

    def __init__(self,  **kwargs):
        super(W1, self).__init__(**kwargs)

w1.kv:

#:kivy 1.10.0

<W1>:
    text:
    Label:
        text: root.text

w2.py:

import kivy from kivy.uix.boxlayout import BoxLayout
# from w1 import W1  # added this to get a working, but the incorrect layout
kivy.require('1.10.0')

class W2(BoxLayout):

    def __init__(self,  **kwargs):
        super(W2, self).__init__(**kwargs)

w2.kv:

#:kivy 1.10.0
#:include w1.kv

<W2>:
    orientation: 'vertical'
    W1:
        text: 'w1.1' 
    W1:
        text: 'w1.2'

main.py:

import kivy
from w2 import W2
from kivy.app import App
kivy.require('1.10.0')


class mainApp(App):

    def build(self):
        pass


if __name__ == '__main__':
    mainApp().run()

main.kv:

#:kivy 1.10.0
#:include w2.kv

W2:

EDIT The overlapping has been resolved, though maybe not correctly. I had W1 inherit from BoxLayout rather than Widget, with the thought that maybe there was a minimum height/width property missing in the base Widget class.

I'm still not certain what the "correct" way to handle importing a widget which has a paired .kv file is, or exactly why I'm getting overlapping widgets when I inherit from Widget; only speculation. enter image description here

Daniel B.
  • 1,254
  • 1
  • 16
  • 35

1 Answers1

0

why are you using two different kv files for this? I would say the proper way would be similar to what i have with my kv file. because you are spliting up things that can be done on a single page and if you need different pages you use the ScreenManager import stuff

main.py:

`
import kivy
from kivy.app import App
from kivy.uix.widgets import Widget
from kivy.uix.label import Label
from kivy.uix.gridlayut import GridLayout

class MyGrid(Widget):
     pass


class MyApp(App):
     def build(self):

 # this calls what we want to show in the kv file
         return MyGrid()



if __name__ == "__main__":
MyApp().run()
`

file is written like this because the App falls off and in order to link the 2 it must have the same name

my.kv: # "<>" Basically links MyGrid from the .py file and then displays the # gridlayout and such GridLayout: rows: 2

        Label:
           text: "whatever"
        
        Label:
           text: "whatever 2"

   
  • 1
    Yes, my specific example could be done in a single page. It is a minimum viable example, but suppose I have one widget that I expect to be in many different widgets in my project. The point is that I was (I no longer even use kivy...) trying to do something that *could not* (or should not) be done in a single page. – Daniel B. Sep 19 '20 at 15:02