Kivy TextInput горизонтальное и вертикальное выравнивание (центрирование текста)

Как центрировать текст по горизонтали в TextInput в Kivy?

У меня есть следующий экран: не тот экран

Но я хочу централизовать свой текст следующим образом: правый экран

А это часть моего kv языка:

        BoxLayout:  
            orientation: 'vertical'
            Label:
                markup: True
                text: '[b] Type something... [/b]'
                size_hint: 1, 0.6
                size: self.parent.size[0], 200
                font_size: self.size[0] * 0.1
                text_size: self.size
                halign: 'center'
                valign: 'middle'

                canvas.before:
                    Color:
                        rgb: 0, 0, 204
                    Rectangle:
                        pos: self.pos
                        size: self.size

            TextInput:
                focus: True

Как я могу центрировать текст моего TextInput?


person Caaarlos    schedule 08.11.2016    source источник
comment
Центрирование текста по горизонтали описано здесь: stackoverflow.com/q/38421741/1542900   -  person Nykakin    schedule 09.11.2016


Ответы (1)


Afaik, нет такой вещи, как выравнивание так же, как в Label, однако вы можете использовать padding, чтобы подтолкнуть позицию туда, куда вы хотите. Имейте в виду, что изменение размера текста повлияет на центрирование, поэтому вам нужно будет пересчитать изменение размера (например, при работе с несколькими устройствами, размерами и т. д.).

Или может быть даже обходной путь, когда вы можете сделать TextInput невидимым, использовать Label для получения события касания для запуска TextInput (что откроет клавиатуру) и изменить текст Label при изменении свойства текста TextInput. Таким образом вы потеряете возможность работать с курсором, и вам нужно будет обрабатывать перенос текста.

Пример:

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, right
        padding_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, bottom
        padding_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(...), очевидно, является методом TextInput. Он работает с ядром виджета, поэтому может быть нестабильным (первый пример, который я опубликовал, содержал ошибки из-за моей ошибки) ^^

Теперь, если значения padding_x дополнены из left и right, вам понадобится только левая сторона (разница только в использовании сложения и вычитания в нужном месте), поэтому давайте сделаем это:

  1. получить самую длинную подстроку в TextInput
  2. получить его ширину (потому что она непоследовательна!) с помощью причудливого метода
  3. вычесть из center[0] координаты

Когда мы уже центрировали ось X, давайте перейдем к Y. Значения padding_y равны top и bottom:

  1. дополнить половину height виджета
  2. получить половину высоты одной строки
  3. умножьте число на количество строк, которые находятся в TextInput
  4. вычесть число из self.height / 2.0
  5. внизу 0, нас это не волнует

Примечание: max() ожидает некоторых аргументов, и если text нет, max() повысит голос. Мы закроем его альтернативным левым отступом для padding_x, используя только центр:

<padding_x with max> if self.text else [self.center[0], 0]
person Peter Badida    schedule 08.11.2016
comment
Спасибо за внимание. Как я могу использовать отступы для централизации? Пробовал, но, как и ты грустишь, у меня были проблемы с разными размерами скринов и разным размером шрифта. Как я могу заставить его работать? - person Caaarlos; 08.11.2016
comment
@Caaarlos добавил пример и объяснение ^^ - person Peter Badida; 08.11.2016
comment
спасибо, я очень ценю вашу помощь. Сейчас работаю, когда будет время, протестирую. Спасибо, еще раз! - person Caaarlos; 09.11.2016
comment
@KeyWeeUser, это сработало, но как заставить его работать с TextInput, у которого нет исходного текста? Просто текст подсказки? - person Caaarlos; 12.11.2016
comment
@Caaarlos отредактировал, нужно совсем немного if для padding_x, где max() вызывает проблему. - person Peter Badida; 12.11.2016
comment
используя этот код, когда у меня нет текста, text_hint и курсор ввода текста перемещаются влево. Можете вы помочь мне? - person Caaarlos; 12.11.2016
comment
@Caaarlos да, я забыл поместить здесь обновленный код с self.center[0] для заполнения x - person Peter Badida; 12.11.2016