2017-07-25 37 views
0

我想在基维启用/禁用Textinput。多个TextInput在那里。 (1)当我点击一个TextInput时,那个特定的TextInput将是可编辑的。 (2)默认情况下,所有内容都将设置为禁用模式。 (3)滚动条应该在那里,假设有数百个输入在那里(我无法提供)。 (4)我面临的另一个问题是:当有数百个输入时,TextInput的文本不能正确显示。那么是否有任何选项可以设置默认大小,以便它不会影响是否只有2-3个输入或100个输入。 (5)TextInput和label处的值应该是动态的,应该存储在全局变量中。 @PalimPalim已经帮助我了解现有的代码。谢谢大家。如何启用/禁用多个TextInput在聚焦在基尼在python

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

回答

1

好吧,首先,你想行动态,以及潜在的巨大的数量,所以你不希望创建并管理所有行自己,这是很慢的两个在填充时间和滚动时,您想使用RecyclevView。

RecycleView获取包含您的小部件数据的字典列表以及显示它们的类,将根据需要创建尽可能多的字段以填充scrollview(它管理的)的可见部分,然后将正确的数据,当您滚动行权,positionning他们给无限流的错觉,这可以让你轻松管理数百个的数千行的,而当前的方式通常会成为以后几百项不可用。

用法很简单,你已经有一个项目清单,但只是里面的文字,让我们将其转换成类型的字典列表,并把它放在应用程序从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

#: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知道在哪里把它,非常简单。

现在,我并没有真正得到一些关于禁用的TextInput,你的意思是集中/聚焦?因为如果你禁用textinputs,触摸它们不会给他们专注,所以(1)将无法实现,如果禁用textinputs,你需要给用户的方式,使他们。

完整的程序

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() 
+0

清晰地解释,谢谢@Tshirtman! – crazyDelight

+0

删除标签的更新很简单,只需删除“text:txtinpt。文本“行规则,它只会在你现在保存该值时更新,对于其他的事情,向你的Row类添加属性,并在字典中使用相同的名称传递它们,它会自动工作。 – Tshirtman

+0

when我在行规则中添加了更多的TextInput,它显示“声明后无效的数据”,并且在字典中传递属性时,它在枚举过程中显示:“ValueError:需要超过2个值才能解包”。 – crazyDelight

相关问题