如何在python中启用/禁用多文本输入聚焦kivy

2024-09-29 02:16:22 发布

您现在位置:Python中文网/ 问答频道 /正文

我试图在kivy中启用/禁用Textinput。有多个文本输入。(1) 当我点击一个TextInput时,这个特定的TextInput是可编辑的。(2) 默认情况下,一切都将设置为禁用模式。(3) 滚动条应该在那里,假设有几百个输入在那里(我无法带来)。(4) 我面临的另一个问题是:当有数百个输入时,TextInput的文本不能正确显示。那么,是否有任何选项可以设置一个默认大小,这样它就不会影响只有2-3个输入还是100个输入。(5) TextInput和label处的值应该是动态的,应该存储在全局变量中。@PalimPalim已经帮助我完成了现有的代码。谢谢大家。在

from kivy.app import App
from kivy.uix.tabbedpanel import TabbedPanel
from kivy.uix.boxlayout import BoxLayout
from kivy.properties import StringProperty
from kivy.uix.textinput import TextInput
from kivy.lang import Builder
kivy.uix.scrollview import ScrollView
from kivy.properties import StringProperty

ROWS = ['ac', 'asd', 'kjhgf', 'b' ,'bn', 'sdf', 'ytrwd', 'hfs' ,'erf', ...]

Builder.load_string("""

<Test>:
    do_default_tab: False

    TabbedPanelItem:
        text: 'page1'
        scrollView:
            size_hint: (None, None)
            size: (400, 400)
            Table:
                padding: 50, 50, 50, 50
                orientation: 'vertical'

<Row>:
    spacing: 50
    size_hint: 1, .9
    txt: txtinpt.text
    Label:
        text: root.txt
    TextInput:
        id: txtinpt
        text: root.txt

    Button:
        text: 'save'

""")
class Table(BoxLayout):
    def __init__(self, **kwargs):
        super(Table, self).__init__(**kwargs)
        for row in ROWS:
            self.add_widget(Row(row))



class Row(BoxLayout):
    txt = StringProperty()
    def __init__(self, row, **kwargs):
        super(Row, self).__init__(**kwargs)
        self.txt = row

class ScrollableLabel(ScrollView):
    text = StringProperty('')

class Test(TabbedPanel):
    pass

class MyApp(App):

    def build(self):
        test = Test()
        return test


if __name__ == '__main__':
    MyApp().run()

kivy gui


Tags: textfromimportselftxtinittextinputkwargs
1条回答
网友
1楼 · 发布于 2024-09-29 02:16:22

好的,首先,您希望使行的数量动态,而且可能很大,所以您不想自己创建和管理所有行,这在填充时和滚动时都非常慢,您需要使用RecyclevView。在

RecycleView获取一个字典列表,其中包含小部件的数据,并由一个类来显示它们,根据需要创建足够多的字典来填充scrollview(它管理的)的可见部分,并在滚动时将正确的数据馈送到正确的行中,定位它们以提供无限流的错觉,这允许您可以毫不费力地管理成百上千的行,而您当前的方式通常在几百个项目之后变得不可用。在

用法很简单,你已经有了一个项目列表,但是只要里面有文本,让我们把它转换成dicts列表,并把它放在应用程序中,以便从kv轻松参考。在

class MyApp(App):
    data = ListProperty()

    def build(self):
        self.data = [{'row_id': i, 'text': x} for i, x in enumerate(ROWS)]
        test = Test()
        return test

现在,让我们用一个回收视图替换你的滚动视图

^{pr2}$

我们会自动调整大小,这里的RecycleView会占用所有的可用空间(你可以调整窗口大小以减少/增加空间),而内部的RecycleBoxLayout可以根据其行的大小进行计算,这是静态定义的,以避免(4)中描述的效果。所以滚动条会在需要时出现,也就是说,当RecycleBoxLayout大于RecycleView时。在

现在,修复Row类,使其在recycleview中具有适当的大小和用法。在

<Row>:
    spacing: 50
    text: txtinpt.text
    Label:
        text: root.text

    TextInput:
        id: txtinpt
        text: root.text

    Button:
        text: 'save'
        on_press:
            app.data[root.row_id]['text'] = root.text

以及

class Row(BoxLayout):
    text = StringProperty()
    row_id = NumericProperty()

这里的想法是,保存将编辑app中的源数据,使用行id来知道将它放在哪里,非常简单。在

现在,我对禁用textinput一点也不了解,你是说专注/不专注?因为如果你禁用文本输入,触摸文本输入不会给它们带来焦点,所以(1)不会实现,如果你禁用文本输入,你需要给用户一种启用它们的方法。在

完整程序

from kivy.app import App
from kivy.uix.tabbedpanel import TabbedPanel
from kivy.uix.boxlayout import BoxLayout
from kivy.properties import StringProperty, ListProperty, NumericProperty
from kivy.lang import Builder
from kivy.uix.scrollview import ScrollView

ROWS = ['ac', 'asd', 'kjhgf', 'b', 'bn', 'sdf', 'ytrwd', 'hfs', 'erf', 'boo']
# now make a lot more of them, to see performances, yep, 100k items...
ROWS = ROWS * 10000

Builder.load_string("""
#:import Factory kivy.factory.Factory
#:import dp kivy.metrics.dp

<Test>:
    do_default_tab: False

    TabbedPanelItem:
        text: 'page1'
        RecycleView:
            # size_hint: (None, None)
            # size: (400, 400)
            data: app.data
            viewclass: Factory.Row
            RecycleBoxLayout:
                padding: 50, 50, 50, 50
                orientation: 'vertical'
                size_hint: 1, None
                size: self.minimum_size
                default_size_hint: 1, None
                default_size: 0, dp(36)

<Row>:
    spacing: 50
    text: txtinpt.text
    Label:
        text: root.text

    TextInput:
        id: txtinpt
        text: root.text

    Button:
        text: 'save'
        on_press:
            app.data[root.row_id]['text'] = root.text

""")


class Row(BoxLayout):
    text = StringProperty()
    row_id = NumericProperty()


class Test(TabbedPanel):
    pass


class MyApp(App):
    data = ListProperty()

    def build(self):
        self.data = [{'row_id': i, 'text': x} for i, x in enumerate(ROWS)]
        test = Test()
        return test


if __name__ == '__main__':
    MyApp().run()

相关问题 更多 >