I'm trying to center the text of a TextInput vertically in Kivy.
But no solution yet.
How can I do a valign for text input in the kv file? Also centering horizontally would be great to know, how to do it.
For labels I have checked the text align example from Kivy and there the alginment is working because there you can use 'valign' and 'halign' to do the alignment, but that's not available for TextInputs.
Maybe a trick with texture_size could help, but I need to check how this works. I have seen such a trick for a label, but I don't know if it works for the TextInput.
Here's my kv code that I have right now:
#: set Buttonheight1 40
BoxLayout:
size_hint_y: None
height: Buttonheight1
Label:
id: _number_label
text: "Number:"
font_size: 10
size_hint_x: None
width: 50
canvas.after:
Color:
rgba: 1,0,0,.5
Rectangle:
pos: self.pos
size: self.size
TextInput:
multiline: False
size_hint_y: None
height: _number_label.height
#padding_top: 10
font_size: 10
text: str(self.font_size)
#text: '%s, %s' % (self.get_center_x(), self.get_center_y()) #position test
Explanation of the kv code:
Buttonheight1 is a constant with kv set
Canvas.after is just for debugging the size of the label
The text of the text input shows font size as dummy text
Maybe it's simple to fix but I'm pretty new to Kivy and haven't found an example for this.
Here is how it looks like at the moment:
(Note: The OK button in the screenshot is not in the kv code above)
Looking at the api, all I could suggest is that you could try using padding, since you can specify:
Padding of the text: [padding_left, padding_top, padding_right, padding_bottom].
padding also accepts a two argument form [padding_horizontal, padding_vertical] and a one argument form [padding].
Maybe usingpadding_top and/or padding_bottom for instance you could center the text vertically.
As already suggested in the comments by AWolf.
This seems to work best:
padding: [0, (self.height-self.line_height)/2]
What worked for me was using pos_hint as follows:
TextInput:
multiline: False
size_hint_y: None
height: _number_label.height
font_size: 10
text: str(self.font_size)
pos_hint: {'center_x': 0.5, 'center_y': 0.5}
I know this is old post .. I just wanna put the answer if anyone search for this again.
Here is the solution:
In the kivy file add this line in the TextInput Properties
padding : 6,self.height/2 - self.font_size/2,6,6
I used this code in my custom text input.
As you see it works fine:
Related
I am making a weather app in which text results are displayed in a scrollview. I have been testing my app and have decided I need to add in x-axis scrolling. In previous times I was making use of just y-axis scrolling but have found that some of the weather results include longer lines that end up not fitting in the screen width and as a result, are being moved down a line which makes the formatting look bad.
I have found that not having anything set in text_size: allows the words to run off the screen without having them forced onto the next line. That is what I needed in regards to that.
Now I am stuck trying to figure out how to have my text results start out being aligned on the left margin of the screen and then allowing the user to scroll across to view entire line(s) if necessary. I am planning on having the run on iPad and iPhone so the screen widths will obviously differ, and I don't want to make the font size any smaller because the user wont be able to read it.
I have tried a whole bunch of different combinations with the layouts in the scrollview, with the parent and child but can't seem to get it right.
I have made a very minimalistic reproducible version that seems to behave the same as my actual app. The scrollview in my homescreen is the culprit. If someone could please help me out with this, that would be so good, thank you.
main.py
from kivy.app import App
from kivy.lang import Builder
from kivy.uix.screenmanager import Screen
class HomeScreen(Screen):
pass
class Results1Screen(Screen):
pass
class TestApp(App):
def build(self):
return Builder.load_file("main.kv")
def on_start(self):
brief_res_1 = self.root.ids["home_screen"].ids["brief_res_1"]
brief_res_1.text = (open("text.txt", "r")).read()
TestApp().run()
main.kv
#:include kv/homescreen.kv
GridLayout:
cols: 1
FloatLayout:
ScreenManager:
size_hint: 1, .95
pos_hint: {"top": .95, "left": 1}
id: screen_manager
HomeScreen:
name: "home_screen"
id: home_screen
homescreen.kv
<HomeScreen>:
BoxLayout:
pos_hint: {"top": .7, "left": 1}
size_hint: 1, 1
size_hint_y: None
ScrollView:
Label:
id: brief_res_1
font_size: '9sp' # need to keep this at '9sp'
do_scroll_x: True
size_hint_y: None
size_hint_x: None
height: self.texture_size[1]
halign: "left" # not too sure if this should be "left"
valign: "center"
text:
text.txt
LINE 1 TEXT TEXT TEXT TEXT TEXT TEXT TEXT TEXT TEXT TEXT TEXT TEXT
LINE 2 TEXT TEXT TEXT TEXT TEXT TEXT
LINE 3 TEXT TEXT TEXT TEXT TEXT TEXT TEXT TEXT TEXT TEXT TEXT TEXT TEXT TEXT TEXT
You can just replace:
height: self.texture_size[1]
with:
size: self.texture_size
If you do not set the width of the Label, it will take the default width of 100, and your x-scrolling will not happen until the width of your HomeScreen gets less than 100 pixels wide.
So I am making an app that requires me to load a list of custom widgets(MDCards) into a RecycleView. Each MDcard will contain two labels and a checkbox. The text can be any size and thus the MDCard has to change its height based on the text that it contains. Here is the part in the kv file that deals with this...NOTE: the text i am adding now is temporary to allow me to create different cards with progressively larger heights.
Custom MDCARD Widget
<IndivualReminderElementBlueprint#MDCard>:
md_bg_color:218/255,68/255,83/255,1
size_hint: 1, None
text: ''
Label:
on_size: root.height = self.height
size_hint: 1, None
text_size: root.width, None
size: self.texture_size
text: root.text
The kv code for the RecycleView class
<ListViewBlueprint>:
viewclass: 'IndivualReminderElementBlueprint'
data: [{"text": f"{i} {'test'*i**2}"} for i in range(20)]
RecycleBoxLayout:
id: container
default_size: None, None
default_size_hint: 1, None
size_hint_y: None
height: self.minimum_height
orientation: 'vertical'
spacing:'20dp'
I am aware that this jerkiness in the scrolling is caused because the size of the widgets is calculated as the user scrolls down which also causes the scroll position to jump randomly. I also looked into this issue posted on Github https://github.com/kivy/kivy/issues/6582 . But i am unable to understand the code at the end or if it will actually fix this problem? I was also wondering if there was any other way to fix this problem? Thanks :)
I am trying to increase the width and the height of a kivyMD button, but it is not supported (size_hint).
•Should I make my own button class that inherits from the Button class ?
•Would that be bad considering I want my app to go on android ?
I would like to know if anyone solved this issue before. Also, if I increase the dimensions of the button, I want the size of the text to change, too...
For example with MDRaised button type
This is how you do it:
MDRaisedButton:
text: "Do Something"
pos_hint: {'center_x': .5, 'center_y': .5}
on_release: app.do_anything()
size: 30, 30
size_hint: None, None
Make sure you set size_hint to None, None and then specify size: width, height
This is an old post but I ran into the same issue.
I had to use it a percentage of the root width and it worked.
Example below:
MDRectangleFlatButton:
text: "Some text"
pos_hint: {"center_x": .5}
size_hint: None, None
width: root.width*0.4
Please tell me why this doesn't work, the whole program works fine, it uses a function inside the main program to get it's text, but it won't scroll so the user won't be able to view the entire output.
<AnswerScreen#Screen>:
input_textb: input_textb
ScrollView:
size_hint: (1, None)
do_scroll_y: True
do_scroll_x: False
bar_width: 4
GridLayout:
padding: root.width * 0.02, root.height * 0.02
cols: 1
size_hint_y: None
size_hint_x: 1
height: self.minimum_height
Label:
id: input_textb
text: ""
font_size: root.height / 25
text_size: self.width, None
Edit:
I had already tried doing the same as many previous answers, in the particular one mentioned in the comments, I got an error saying "NoneType" has no attribute "bind".
I removed the size hint, it still doesn't work, but thanks anyway.
The text is definitely long enough.
I believe the label's size is not set, which i agree can be confusing at first, Label has a widget size (size as all widgets) and a texture_size, which is set to the actual size of the displayed text, kivy doesn't relate these two in any particular way at first, and it's up to you to decide how one influences the other, you did half of the work in setting text_size to (width, None), which forces the texture into having the width of the widget, but you are missing the other part of the deal, which is that you want to be the widget to be as tall as the generated texture. For this size to be effective, you also have to disable size_hint_y for Label, since it's in a GridLayout.
Label:
id: input_textb
text: ""
font_size: root.height / 25
text_size: self.width, None
height: self.texture_size[1]
size_hint_y: None
and you should be all set.
You should set a value for the property scroll_y of the ScrollView between 0 and 1.
I want to create a view of some parameters. A parameter has a name, a description and a value.This should look like:
parameter name, slider, numeric display
description
in kivy you can use a BoxLayout in the kv language:
BoxLayout:
orientation: 'vertical'
BoxLayout:
orientation: 'horizontal'
Label:
text: 'warp power'
Slider:
id: pwSlider
min: 0.0
max: 1.0
value: 0.0
TextInput:
text: "%.4f" % pwSlider.value
multiline: False
on_text_validate: pwSlider.value = float(self.text)
Label:
markup: True
text: '[color=a0a0a0]sets the warp power[/color]'
The problem is, that the description and paramter name does not start at the same x position.
A other problem ist, that I want to scale the text x-size down to the size of the text inside.
any ideas?
To restrict a label width to the texture width (same logic for height if you need), you can:
Label:
size_hint_x: None
width: self.texture_size[0]
If you use a such label in a BoxLayout, it will be left/bottom aligned by default. For your information, you can use pos_hint to place it somewhere else.
I guess in your example, just using the method described above in your description Label will be enough.