Kivy-как разрешить горизонтальную и вертикальную прокрутку в TextInput? - PullRequest
0 голосов
/ 14 декабря 2018

Я довольно новичок в Python и Kivy и хочу сделать простой редактор кода.Я попытался использовать файл Kivy (.kv) для создания хорошего прототипа:

<Label>:
    font_name:'Fura Code Retina Nerd Font Complete.otf'
    font_size:'18sp'
<GridLayout>:
    cols:3
    rows:1
    Label:
        text:"Bars"
        size_hint_x: None
        width: 50
    Label:
        canvas.before:
            Color:
                rgb:0.085,0.095,0.085
            Rectangle:
                pos: self.pos
                size: self.size
        text:"Bars-result"
        size_hint_x: None
        width: 170
    ScrollView:
        TextInput:
            font_size: '18sp'
            cursor_color: [255,255,255,1]
            background_color: (.17, .18, .17, 1)
            foreground_color:[255,255,255,1]
            font_name: 'Fura Code Retina Nerd Font Complete.otf'
            selection_color: (1,1,1,0.125)

Возможно, вы обнаружили, что если вы превысите вертикальное поле, вы можете прокрутить обратно вверх (однако без реальной полосы прокрутки),Однако при горизонтальном положении этого не происходит, фактически мы переходим к следующей строке.Я хочу сделать его прокручиваемым по осям x и y и иметь полосу прокрутки для обоих.
Спасибо за любую помощь, и, если возможно, помощь по документации также полезна (однако, я очень быстро путаюсь с документацией Киви, смеется)

Ответы [ 2 ]

0 голосов
/ 25 июля 2019

Вот упрощенное и слегка улучшенное рабочее решение.Ключевые отличия:

  • поле ввода с одной строкой, которое заполняет поле вывода с возможностью прокрутки с одной строкой
  • прокрутка ограничена горизонтальной
  • предотвращена прокрутка

textinputscrolling.kv

<TextInputScrolling>:
    textInput: txt_input
    textOutput: txt_output
    scroller: scroll_view

    orientation: 'vertical'
    BoxLayout:
        orientation: 'vertical'
        canvas.before:
            Rectangle:
                pos: self.pos
                size: self.size
        BoxLayout:
            orientation: 'vertical'
            size_hint_y: None
            height: "56dp"
            canvas.before:
                Color:
                    rgb: [0,0,0]
                Rectangle:
                    pos: self.pos
                    size: self.size
            TextInput:
                id: txt_input
                focus: True
                multiline: False
                on_text_validate: root.submitRequest() # ENTER triggers root.submitRequest()

            GridLayout:
                cols: 2
                ScrollView:
                    id: scroll_view
                    do_scroll_y: False # limiting to horizontal scrolling
                    effect_cls: "ScrollEffect" # prevents overscrolling
                    size_hint_x: 3
                    TextInput:
                        id: txt_output
                        size_hint: (None, None) # warning: if not there, scrolling not working !
                        width: scroll_view.width
                        cursor_color: [255,255,255,1]
                        background_color: (.17, .18, .17, 1)
                        foreground_color:[255,255,255,1]
                        selection_color: (1,1,1,0.125)
                        multiline: False
                        read_only: True
                        on_text: root.text_changed()
                Button:
                    id: clear_output_Button
                    text: 'Clear'
                    size_hint_x: 1
                    width: 130
                    on_press: root.clearAll()

textinputscrolling.py

from kivy.app import App
from kivy.config import Config
from kivy.properties import ObjectProperty
from kivy.uix.boxlayout import BoxLayout


class TextInputScrolling(BoxLayout):
    textInput = ObjectProperty()
    scroller = ObjectProperty()
    textOutput = ObjectProperty()

    def submitRequest(self):
        self.textOutput.text = self.textInput.text

    def text_changed(self, *args):
        width_calc = self.scroller.width
        for line_label in self.textOutput._lines_labels:
            width_calc = max(width_calc, line_label.width + 20)   # add 20 to avoid automatically creating a new line
        self.textOutput.width = width_calc

    def clearAll(self):
        self.textInput.text = ''
        self.textOutput.text = ''


class TextInputScrollingApp(App):
    def build(self):
        Config.set('graphics', 'width', '200')
        Config.set('graphics', 'height', '60')
        Config.write()

        self.gui = TextInputScrolling()
        return self.gui

TextInputScrollingApp().run()

Результат

enter image description here

0 голосов
/ 14 декабря 2018

Вам необходимо отрегулировать ширину TextInput в соответствии с длиной строк текста в нем.К сожалению, не существует простого способа динамической регулировки ширины виджета TextInput.Вот взлом, который я думаю, будет работать.Обратите внимание, что здесь используются внутренние элементы TextInput, поэтому он может сломаться, если код TextInput изменится в будущих выпусках:

from kivy.app import App
from kivy.lang import Builder
from kivy.uix.gridlayout import GridLayout

Builder.load_string('''
<Label>:
    font_name:'Fura Code Retina Nerd Font Complete.otf'
    font_size:'18sp'
<GridLayout>:
    cols:3
    rows:1
    Label:
        text:"Bars"
        size_hint_x: None
        width: 50
    Label:
        canvas.before:
            Color:
                rgb:0.085,0.095,0.085
            Rectangle:
                pos: self.pos
                size: self.size
        text:"Bars-result"
        size_hint_x: None
        width: 170
    ScrollView:
        id:scroller
        TextInput:
            id: ti
            size_hint: (None, None)
            width: scroller.width
            height: max(self.minimum_height, scroller.height)
            font_size: '18sp'
            cursor_color: [255,255,255,1]
            background_color: (.17, .18, .17, 1)
            foreground_color:[255,255,255,1]
            font_name: 'Fura Code Retina Nerd Font Complete.otf'
            selection_color: (1,1,1,0.125)
            on_text: app.text_changed()
''')

class ScrollBothApp(App):
    def build(self):
        self.grid = GridLayout()
        return self.grid

    def text_changed(self, *args):
        width_calc = self.grid.ids.scroller.width
        for line_label in self.grid.ids.ti._lines_labels:
            width_calc = max(width_calc, line_label.width + 20)   # add 20 to avoid automatically creating a new line
        self.grid.ids.ti.width = width_calc



ScrollBothApp().run()
...