gusftaft
gusftaft

Reputation: 43

How to make editable label work in kivy

Following code opens window with label on top and label turns to textinput once you click on it.

But, once you start typing and insert first key (any key), text gets shortened, and you lose part of the text suddenly. For example: you click on label > textinput appears > you type '1' > text becomes 'Press here and then try 1'.

How to change below code to stop text disappearing?

import kivy
kivy.require('1.10.1')

from kivy.uix.floatlayout import FloatLayout
from kivy.uix.textinput import TextInput
from kivy.uix.label import Label
from kivy.base import runTouchApp
from kivy.properties import BooleanProperty, ObjectProperty

#https://github.com/kivy/kivy/wiki/Editable-Label
class EditableLabel(Label):

    edit = BooleanProperty(False)

    textinput = ObjectProperty(None, allownone=True)

    def on_touch_down(self, touch):
        if self.collide_point(*touch.pos) and not self.edit:
            self.edit = True
        return super(EditableLabel, self).on_touch_down(touch)

    def on_edit(self, instance, value):
        if not value:
            if self.textinput:
                self.remove_widget(self.textinput)
            return
        self.textinput = t = TextInput(
                text=self.text, size_hint=(None, None),
                font_size=self.font_size, font_name=self.font_name,
                pos=self.pos, size=self.size, multiline=False)
        self.bind(pos=t.setter('pos'), size=t.setter('size'))
        self.add_widget(self.textinput)
        t.bind(on_text_validate=self.on_text_validate, focus=self.on_text_focus)

    def on_text_validate(self, instance):
        self.text = instance.text
        self.edit = False

    def on_text_focus(self, instance, focus):
        if focus is False:
            self.text = instance.text
            self.edit = False

if __name__ == '__main__':

    root = FloatLayout()

    lbl = 'Press here and then try to edit (type a character), but text gets shortened suddenly.'
    label = EditableLabel(text=lbl, size_hint_y=None, height=50, pos_hint={'top': 1})
    root.add_widget(label)

    runTouchApp(root)

Upvotes: 0

Views: 430

Answers (1)

eyllanesc
eyllanesc

Reputation: 243887

According to the docs:

The selection is automatically updated when the cursor position changes. You can get the currently selected text from the TextInput.selection_text property.

and in your case when you click on the Label and appear in TextInput the cursor changes position so a text is selected. And when a text is selected and you write something it is replaced, that's why the text disappears.

The solution is to clean the selection:

from kivy.clock import Clock

class EditableLabel(Label):
    [...]
    def on_edit(self, instance, value):
        if not value:
            if self.textinput:
                self.remove_widget(self.textinput)
            return
        self.textinput = t = TextInput(
                text=self.text, size_hint=(None, None),
                font_size=self.font_size, font_name=self.font_name,
                pos=self.pos, size=self.size, multiline=False)
        self.bind(pos=t.setter('pos'), size=t.setter('size'))
        self.add_widget(self.textinput)
        t.bind(on_text_validate=self.on_text_validate, focus=self.on_text_focus)
        Clock.schedule_once(lambda dt: self.textinput.cancel_selection())

Upvotes: 1

Related Questions