2017-07-25 32 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

相關問題