I am new in Kivy. I would like to create an app that takes user text input, then display it. But when the user input is very long, I want the display area to be scrollable.
I have done some tutorials and can do both things separately, but I have troubles putting them altogether.
Here is the code to allow scrollable text:
__version__ = '1.0.1'
from kivy.app import App
from kivy.uix.boxlayout import BoxLayout
from kivy.uix.button import Button
from kivy.uix.widget import Widget
from kivy.uix.label import Label
from kivy.uix.textinput import TextInput
from kivy.uix.scrollview import ScrollView
import warnings
import string
from kivy.base import runTouchApp
from kivy.lang import Builder
from kivy.properties import StringProperty
Builder.load_string('''
<ScrolllabelLabel>:
Label:
text: root.text
font_size: 50
text_size: self.width, None
size_hint_y: None
height: self.texture_size[1]
''')
class ScrolllabelLabel(ScrollView):
text = StringProperty('srgsdrgsdfh dsfg dvgf vgsdfv srfvsdfsdrfv sevrv sdrfv serv serv serv servsrd vsv srvsdrfvvv' * 10)
runTouchApp(ScrolllabelLabel())
And here is the code to display what you type:
__version__ = '1.0.1'
from kivy.app import App
from kivy.uix.boxlayout import BoxLayout
from kivy.uix.gridlayout import GridLayout
from kivy.uix.button import Button
from kivy.uix.widget import Widget
from kivy.uix.label import Label
from kivy.uix.textinput import TextInput
from kivy.uix.scrollview import ScrollView
import warnings
import string
from kivy.base import runTouchApp
from kivy.lang import Builder
from kivy.properties import StringProperty
class SomeApp(App):
def build(self):
grid = GridLayout(cols=1, size_hint_x=None, width="600dp")
self.lbl0 = Label(text='Tap and type a word/phrase below') # create a label instance
grid.add_widget(self.lbl0) # physically add the label onto the layout
self.txt1 = TextInput(text='', multiline=False) # create a text input instance
grid.add_widget(self.txt1) # physically add the text input onto the layout
self.lbl1 = Label(text='Display') # create a label instance
grid.add_widget(self.lbl1) # physically add the label onto the layout
btn1 = Button(text='Press') # create a button instance
btn1.bind(on_press=self.mirror) # binding the button with the function below
grid.add_widget(btn1)
return grid
def mirror(self, userInput):
self.lbl1.text = self.txt1.text
SomeApp().run()
But I can't combine them:
__version__ = '1.0.1'
from kivy.app import App
from kivy.uix.boxlayout import BoxLayout
from kivy.uix.gridlayout import GridLayout
from kivy.uix.button import Button
from kivy.uix.widget import Widget
from kivy.uix.label import Label
from kivy.uix.textinput import TextInput
from kivy.uix.scrollview import ScrollView
import warnings
import string
from kivy.base import runTouchApp
from kivy.lang import Builder
from kivy.properties import StringProperty
Builder.load_string('''
<ScrolllabelLabel>:
Label:
text: root.text
font_size: 50
text_size: self.width, None
size_hint_y: None
height: self.texture_size[1]
''')
class ScrolllabelLabel(ScrollView):
def __init__(self, **kwargs):
self.txt0 = StringProperty()
class SomeApp(App):
def build(self):
grid = GridLayout(cols=1, size_hint_x=None, width="600dp")
self.lbl0 = Label(text='Tap and type a word/phrase below') # create a label instance
grid.add_widget(self.lbl0) # physically add the label onto the layout
self.txt1 = TextInput(text='', multiline=False) # create a text input instance
grid.add_widget(self.txt1) # physically add the text input onto the layout
btn1 = Button(text='Press') # create a button instance
btn1.bind(on_press=self.displayFunc) # binding the button with the function below
grid.add_widget(btn1)
# Add scrolling text
"""self.lbl1 = Label(text='Display') # create a label instance
grid.add_widget(self.lbl1) # physically add the label onto the layout"""
scrollWidget = ScrolllabelLabel(text=self.lbl1.text)
grid.add_widget(scrollWidget)
return grid
def displayFunc(self, userInput):
self.lbl1.text = self.txt1
SomeApp().run()
I got this error:
AttributeError: 'SomeApp' object has no attribute 'lbl1'
You must carefully specify the size of your content to get the desired scroll/pan effect. By default, the size_hint is (1, 1), so the content size will fit your ScrollView exactly (you will have nothing to scroll). You must deactivate at least one of the size_hint instructions (x or y) of the child to enable scrolling.
We can make the text scrollable in flutter using these 2 widgets: Expanded Class: A widget that expands a child of a Row, Column, or Flex so that the child fills the available space. SingleChildScrollView Class: A box in which a single widget can be scrolled.
What you did is multiline=False
therefore the app will behave that way and doesn't matter how big you make TextInput
, it'll still be one line. Use multiline=True
for your default TextInput and it'll wrap input properly.
Then I see you already have a body for scrollable label, so just use the default one, use that default class and feed the text
variable of ScrolllabelLabel
in your first file with your output.
from kivy.app import App
from kivy.uix.boxlayout import BoxLayout
from kivy.uix.gridlayout import GridLayout
from kivy.uix.button import Button
from kivy.uix.widget import Widget
from kivy.uix.label import Label
from kivy.uix.textinput import TextInput
from kivy.uix.scrollview import ScrollView
import warnings
import string
from kivy.base import runTouchApp
from kivy.lang import Builder
from kivy.properties import StringProperty
Builder.load_string('''
<ScrolllabelLabel>:
Label:
text: root.text
font_size: 50
text_size: self.width, None
size_hint_y: None
height: self.texture_size[1]
''')
class ScrolllabelLabel(ScrollView):
text = StringProperty('')
class SomeApp(App):
def build(self):
grid = GridLayout(cols=1, size_hint_x=None, width="600dp")
self.lbl0 = Label(text='Tap and type a word/phrase below') # create a label instance
grid.add_widget(self.lbl0) # physically add the label onto the layout
self.txt1 = TextInput(text='', multiline=True) # create a text input instance
grid.add_widget(self.txt1) # physically add the text input onto the layout
self.lbl1 = ScrolllabelLabel(text='Display') # create a label instance
grid.add_widget(self.lbl1) # physically add the label onto the layout
btn1 = Button(text='Press') # create a button instance
btn1.bind(on_press=self.mirror) # binding the button with the function below
grid.add_widget(btn1)
return grid
def mirror(self, userInput):
self.lbl1.text = self.txt1.text
SomeApp().run()
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With