Alexstuica120
Alexstuica120

Reputation: 114

Kivy label multiline text

I want to make a program that has input some letters and it gives in real time all the combinations of words but i can display only a few because i can't figure out how to use multiline.I haven't used kivy for a very long time. Can anyone help me please?

from kivy.app import App
from kivy.uix.boxlayout import BoxLayout
from kivy.uix.label import Label
from kivy.uix.textinput import TextInput
from kivy.uix.button import Button
from kivy.uix.floatlayout import FloatLayout
import itertools



class Screen(BoxLayout):  

    def __init__(self, **kwargs ):
        super(Screen, self).__init__(**kwargs)
        self.orientation = "vertical"
        cuvinte = " "
        boxlayout2 = BoxLayout()
        button = Button()
        txt_instructions = Label(text = "Introduce your letters without any spaces between them")
        self.add_widget(txt_instructions)
        my_user_input = TextInput()
        boxlayout2.add_widget(my_user_input)
        self.add_widget(boxlayout2)   
        my_output = Label(halign = 'center')        
        self.add_widget(my_output)
        def callback(instance, value):
            cuvinte = " "
            lista2 = []
            lista3 = []
            n = value
            lista = list(n)
            for i in range(len(lista)):
                for word in itertools.permutations(lista):
                    lista2.append(''.join(word[0:len(word)-i]))

            for i in lista2:
                if i not in lista3:
                    lista3.append(i)
            lista3.sort()
            cuvinte = ' '.join(str(e) for e in lista3)
            my_output.text = cuvinte

        my_user_input.bind(text=callback)




class MyApp(App):

    def build(self):
        return Screen()


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

Upvotes: 4

Views: 11613

Answers (2)

George Bou
George Bou

Reputation: 588

To use a Label that automatically BOTH wraps its text AND is displayed multi-line when needed, u have to do a couple of things.

1) According to the official Kivy Tutorial you need to set the size and position of the label so that it can follow the changes of its parent size.

2) Create a function that updates the size according to the size of the text displayed in the label

3) Bind the Label with the update function

So your code could look like this:

from kivy.app import App
from kivy.uix.boxlayout import BoxLayout
from kivy.uix.label import Label
from kivy.uix.textinput import TextInput
from kivy.uix.button import Button
from kivy.uix.floatlayout import FloatLayout
import itertools


class Screen(BoxLayout):

    def __init__(self, **kwargs ):
        super(Screen, self).__init__(**kwargs)
        self.orientation = "vertical"
        cuvinte = " "
        boxlayout2 = BoxLayout()
        button = Button()
        txt_instructions = Label(text = "Introduce your letters without any spaces between them")
        self.add_widget(txt_instructions)
        my_user_input = TextInput()
        boxlayout2.add_widget(my_user_input)
        self.add_widget(boxlayout2)

        """THE LABEL HAS ITS SIZE AND POSITION SET TO FOLLOW THE PARENT'S"""
        self.my_output = Label(text_size= (None,None),
                          pos_hint={'center_x': 0.5, 'center_y': .95},
                          size_hint_y=None,
                          size = self.size,
                          height = self.size[1],
                          halign="center",
                          valign = "middle",)

        self.add_widget(self.my_output)

        """BINDING THE LABEL TO THE FUNCTION THAT UPDATES THE SIZE"""
        self.my_output.bind(size=self.setting_function)

        def callback(instance, value):
            cuvinte = " "
            lista2 = []
            lista3 = []
            n = value
            lista = list(n)
            for i in range(len(lista)):
                for word in itertools.permutations(lista):
                    lista2.append(''.join(word[0:len(word)-i]))

            for i in lista2:
                if i not in lista3:
                    lista3.append(i)
            lista3.sort()
            cuvinte = ' '.join(str(e) for e in lista3)
            self.my_output.text = cuvinte

        my_user_input.bind(text=callback)

    def setting_function(self, *args):
        """FUNCTION TO UPDATE THE LABEL TO ADJUST ITSELF ACCORDING TO SCREEN SIZE CHANGES"""
        self.my_output.pos_hint = {'center_x': 0.5, 'center_y': .85}
        self.my_output.text_size=self.size


class MyApp(App):

    def build(self):
        return Screen()


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

Now your text gets wrapped and displayed multi-line: * When the text size changes * When the window size changes

P.S. When the letters become too many, the program freezes due to insufficient CPU/RAM. You should consider restricting the number of letters a user can type.

Upvotes: 1

ikolim
ikolim

Reputation: 16041

Add multiline=True in your TextInput widget

my_user_input = TextInput(multiline=True)

Upvotes: 6

Related Questions