Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Align text to edge of Label in ScrollView in kivy

I am trying to make Label scrollable horizontally and want halign:"right and valign:middle as per below code

ScrollView:

  Label:    
    id:maindisplay
    text:"0"
    font_size:"50sp"
    text_size: None ,self.height[1] #  Set the text wrap box height
    size_hint_x:None
    width: self.texture_size[0]

#Following part is not working
    halign: 'right'
    valign: 'middle'

enter image description here

like image 711
Nisarg Avatar asked Oct 19 '22 16:10

Nisarg


1 Answers

The crucial point here is the width of the text. If it is set to None, it is unconstrained, and if the text is wider than the parent, it can be scrolled. However, if the text only requires a fraction of the width of the parent, the text will be centered inside the label (albeit multiple lines will still be right aligned). On the other hand, if text_size is statically set to a finite value, text that doesn't fit will wrap and there is never going to be scrolling. The hacky solution is to set text_size: 8000, self.height (something very wide, unlikely to ever occur). That allows scrolling, but is ugly (and one could accidentally scroll into the area where nothing is displayed).

Instead, we change the text_width dynamically. When text changes, we first remove the width constraint. We then let the label update its contents, and set text_size to be as wide as it has to be to fit the text, but at least as wide as the parent.

The other settings make sure the label itself is at least as wide as the parent (width) and that the ScrollView starts at its right edge (scroll_x:1)

Here is a complete example:

from kivy.app import App
from kivy.lang import Builder
from kivy.config import Config
from kivy.clock import Clock
from kivy.properties import StringProperty, NumericProperty

kv = '''ScrollView:
  scroll_x: 1
  Label:
    canvas.before:
      Color:
        rgba:1,0,0,1
      Rectangle:
        pos: self.parent.pos
        size: self.size
    id:maindisplay
    text:"2"
    font_size:"50sp"
    text_size: None, self.height
    size_hint_x: None
    width:  max(self.texture_size[0], self.parent.width)
    halign: 'right'
    valign: 'middle'
    on_text: app.txt_cb(*args)
'''

class QApp(App):
    txt = StringProperty("1")
    num = NumericProperty(0)

    def add_string(self, dt=0):
        self.num += 1
        self.txt += "%i" % self.num
        self.root.ids.maindisplay.text = self.txt

    def txt_cb(self, obj, text):
        obj.text_size = (None, obj.height)
        obj.texture_update()
        obj.text_size = (max(obj._label.content_width, obj.parent.width), obj.height)

    def build(self):
        Clock.schedule_once(lambda dt:self.txt_cb(self.root.ids.maindisplay, ""), 0)
        Clock.schedule_interval(self.add_string, .5)
        return Builder.load_string(kv)

if __name__ == '__main__':
    QApp().run()
like image 135
zeeMonkeez Avatar answered Nov 11 '22 09:11

zeeMonkeez