I have a big knowledge gap about how Kivy sizes the various elements, and it is being resistant to my attempts to fix it.
Here is my stopwatch.kv
file
#:kivy 1.11.1
<StopWatch>:
BoxLayout:
orientation: 'vertical'
canvas.before:
Color:
rgba: .2, .2, .2, 1
Rectangle:
pos: self.pos
size: self.size
Label:
text: "A long piece of text #1"
size: self.texture_size
canvas.before:
Color:
rgba: .5, .1, .1, 1
Rectangle:
pos: self.pos
size: self.size
Label:
text: "A long piece of text #2"
size: self.texture_size
text_size: root.width, None
canvas.before:
Color:
rgba: .5, .5, .1, 1
Rectangle:
pos: self.pos
size: self.size
Here is main.py
:
from kivy.app import App
from kivy.uix.widget import Widget
class StopWatch(Widget):
pass
class StopWatchApp(App):
def build(self):
sw = StopWatch()
return sw
if __name__ == '__main__':
StopWatchApp().run()
I have figured out the size of the window (on my desktop) is, by default, unrelated to its contents. Okay.
I have figured out the size of the BoxLayout
is, by default, unrelated to the window size. Instead, it is large enough to enclose its children widgets. Okay.
I have figured out that the size of a Label
is, by default, unrelated to the size of its text contents. Instead, I think it is 100x100, but I haven't found that documented.
If you want a label to be big enough to cover the text (and hence the BoxLayout to cover the text), you have to specify:
size: self.texture_size
Okay. But I do that for the first label, and it still exceeds its label size (which I use a rectangle coloured red to visualise.)
So, I try to specify the text_size in the second label - making it the full width of the window - but its text doesn't appear at all!
I know I am missing something obvious, but reading the manuals hasn't helped.
The problem is that your StopWatch
extends Widget
, and Widget
is not intended as a container. See the Widget Class.
Note the part that says:
So, your StopWatch
will be size (100,100)
, and your Labels
are wider than that. A simple solution is to change your StopWatch
to extend a Layout
like this:
class StopWatch(BoxLayout):
pass
Then you can rewrite your kv
as:
#:kivy 1.11.1
<StopWatch>:
orientation: 'vertical'
canvas.before:
Color:
rgba: .2, .2, .2, 1
Rectangle:
pos: self.pos
size: self.size
Label:
text: "A long piece of text #1"
size: self.texture_size
canvas.before:
Color:
rgba: .5, .1, .1, 1
Rectangle:
pos: self.pos
size: self.size
Label:
text: "A long piece of text #2"
size: self.texture_size
text_size: root.width, None
canvas.before:
Color:
rgba: .5, .5, .1, 1
Rectangle:
pos: self.pos
size: self.size
Note that the BoxLayout
has been removed from the kv
, since StopWatch
is now a BoxLayout
. Also, note that your size
properties of the Labels
in your kv
will have no effect unless you set size_hint
to (None, None)
, since size_hint
takes precedence over size
.