【问题标题】:how to enable/disable multiple TextInput on focusing in kivy in python如何在python中的kivy中启用/禁用多个TextInput
【发布时间】:2017-12-31 06:02:30
【问题描述】:

我正在尝试在 kivy 中启用/禁用 Textinput。有多个 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()

【问题讨论】:

    标签: python user-interface kivy edit textinput


    【解决方案1】:

    好的,首先,您想让行数动态化,并且可能很大,因此您不想自己创建和管理所有行,这在填充时和滚动时都非常慢,您想要使用 RecyclevView。

    RecycleView 获取一个字典列表,其中包含您的小部件的数据,以及一个显示它们的类,将根据需要创建尽可能多的字典来填充滚动视图(由它管理)的可见部分,并提供正确的滚动时将数据移到正确的行,将它们定位以提供无限流的错觉,这使您可以轻松管理数百 数千行,而您当前的方式通常在数百行后变得无法使用项目。

    用法很简单,你已经有了一个item列表,但是里面只有文字,我们把它转换成dicts列表,放到app里方便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
    

    现在,让我们用 RecycleView 替换您的 ScrollView

    #:import Factory kivy.factory.Factory
    
    <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
                    size_hint_y: None
                    size: self.minimum_size
                    default_size_hint: 1, None
                    default_size: 0, dp(36)  # width is overriden by size_hint_x
                    orientation: 'vertical'
    

    我们自动调整大小,这里 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()
    

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

    现在,我并没有真正了解禁用文本输入,您的意思是聚焦/不聚焦吗?因为如果你禁用文本输入,触摸它们不会给他们焦点,所以(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()
    

    【讨论】:

    • 删除标签的更新很简单,只需删除规则中的“text:txtinpt.text”行,现在保存值时才会更新。对于其他事情,将属性添加到您的 Row 类,并使用相同的名称将它们传递到 dict 中,它会自动工作。
    • 当我在 Row 规则中添加更多 TextInput 时,它显示“声明后数据无效”,并且在 dict 中传递属性时,它显示:“ValueError:需要超过 2 个值才能解包" 在枚举过程中。
    猜你喜欢
    • 2017-12-27
    • 2017-12-19
    • 1970-01-01
    • 1970-01-01
    • 2021-11-03
    • 1970-01-01
    • 1970-01-01
    • 2017-11-01
    • 1970-01-01
    相关资源
    最近更新 更多