Kivy TextInput horizontal and vertical align (centering text)

2024/11/16 19:01:39

How to center a text horizontally in a TextInput in Kivy?

I have the following screen: wrong screen

But I want to centralize my text like this: right screen

And this is part of my kv language:

        BoxLayout:  orientation: 'vertical'Label:markup: Truetext: '[b] Type something... [/b]'size_hint: 1, 0.6size: self.parent.size[0], 200font_size: self.size[0] * 0.1text_size: self.sizehalign: 'center'valign: 'middle'canvas.before:Color:rgb: 0, 0, 204Rectangle:pos: self.possize: self.sizeTextInput:focus: True

How can I center my TextInput's text?

Answer

Afaik, there's no such thing as aligning in the same way as it's in Label, however, you can use padding to push the position wherever you want. Keep in mind that changing the size of text will affect the centering, therefore you'll need to recalculate on change of size (e.g. when working with multiple devices, sizes, etc).

Or there could be even a workaround, where you could make TextInput invisible, use Label to fetch touch event to trigger TextInput (which would open keyboard) and change Label's text on change of TextInput's text property. You'll lose the possibility to work with cursor this way and you'll need to handle wrapping text.

Example:

from kivy.app import App
from kivy.lang import Builder
from kivy.uix.boxlayout import BoxLayout
Builder.load_string('''
<Test>:TextInput:text: 't'font_size: 60# left, rightpadding_x:[self.center[0] - self._get_text_width(max(self._lines, key=len), self.tab_width, self._label_cached) / 2.0,0] if self.text else [self.center[0], 0]# top, bottompadding_y: [self.height / 2.0 - (self.line_height / 2.0) * len(self._lines), 0]
''')
class Test(BoxLayout):pass
class TestApp(App):def build(self):return Test()
TestApp().run()

self._get_text_width(...) is obviously a method of a TextInput. It's working with the core of the widget so it might be unstable (first example I posted was buggy because of my mistake) ^^

Now if padding_x's values padd from left and right, you'll need only the left side (the difference is only in using addition and substraction in the right place), so let's do that:

  1. get the longest substring in the TextInput
  2. get its width (because it's not consistent!) via the fancy method
  3. substract from center[0] coordinate

When we've already centered the X axis, let's go to the Y. padding_y's values are top and bottom:

  1. padd down the half of the widget's height
  2. get a half of a height of a single line
  3. multiply the number by the count of lines that are in TextInput
  4. substract the number from self.height / 2.0
  5. bottom is 0, we don't care about it

Note: max() expects some arguments and if there's no text, max() will raise its voice. We'll shut it with an alternative left padding for padding_x using only the center:

<padding_x with max> if self.text else [self.center[0], 0]
https://en.xdnf.cn/q/71639.html

Related Q&A

How to capture python SSL(HTTPS) connection through fiddler2

Im trying to capture python SSL(HTTPS) connections through Fiddler2 local proxy. But I only got an error.codeimport requests requests.get("https://www.python.org", proxies={"http": …

removing leading 0 from matplotlib tick label formatting

How can I change the ticklabels of numeric decimal data (say between 0 and 1) to be "0", ".1", ".2" rather than "0.0", "0.1", "0.2" in matplo…

How do I check if an iterator is actually an iterator container?

I have a dummy example of an iterator container below (the real one reads a file too large to fit in memory):class DummyIterator:def __init__(self, max_value):self.max_value = max_valuedef __iter__(sel…

Python Terminated Thread Cannot Restart

I have a thread that gets executed when some action occurs. Given the logic of the program, the thread cannot possibly be started while another instance of it is still running. Yet when I call it a sec…

TypeError: NoneType object is not subscriptable [duplicate]

This question already has an answer here:mysqldb .. NoneType object is not subscriptable(1 answer)Closed 8 years ago.The error: names = curfetchone()[0]TypeError: NoneType object is not subscriptable. …

Where can I find numpy.where() source code? [duplicate]

This question already has answers here:How do I use numpy.where()? What should I pass, and what does the result mean? [closed](2 answers)Closed 4 years ago.I have already found the source for the num…

NSUserNotificationCenter.defaultUserNotificationCenter() returns None in python

I am trying to connect to the Mountain Lion notification center via python. Ive installed pyobjc and am following the instructions here and here. Also see: Working with Mountain Lions Notification Cent…

Flask app hangs while processing the request

I have a simple flask app, single page, upload html and then do some processing on it on the POST; at POST request; i am using beautifulsoup, pandas and usually it takes 5-10 sec to complete the task. …

How do I make a server listen on multiple ports

I would like to listen on 100 different TCP port with the same server. Heres what Im currently doing:-import socket import selectdef main():server_socket = socket.socket(socket.AF_INET, socket.SOCK_STR…

Django REST Framework: return 404 (not 400) on POST if related field does not exist?

Im developing a REST API which takes POST requests from some really brain-dead software which cant PATCH or anything else. The POSTs are to update Model objects which already exist in the database.Spec…