Nirdesh Kumawat
Nirdesh Kumawat

Reputation: 406

Python :How to set focus on dynamic TextInput

I am using python-2.7 and kivy.
When i run test.py then screen looks like attached image. When i click on +Add More button then row will be add dynamic. If i fill value like attached image after click on Ok button then i can find blank value TextInput using this code.

        a = 1
        for val in values:
            print(val)
            if val[1] == "":
                print("row"+str(a) +" TextInput 1 is required")
                break;

            if val[2] == "":
                print("row"+str(a) +" TextInput 2 is required")
                break;
            a = a+1

But can someone tell me how to set focus into first blank TextInput like attached image.

enter image description here

test.py

from kivy.uix.screenmanager import Screen
from kivy.app import App
from kivy.lang import Builder
from kivy.core.window import Window
from kivy.uix.boxlayout import BoxLayout
from kivy.properties import StringProperty
from kivy.uix.textinput import TextInput
from kivy.uix.button import Button

Window.size = (450, 525)


class display(Screen):

    def add_more(self):
        self.ids.rows.add_row()

    def insert(self):

        values = []
        rows = self.ids.rows

        for row in reversed(rows.children):
            vals = []
            for ch in reversed(row.children):
                if isinstance(ch, TextInput):
                    vals.append(ch.text)
                if isinstance(ch, Button):
                    vals.insert(0, ch.text)
            values.append(vals)

        a = 1
        for val in values:
            print(val)
            if val[1] == "":
                print("row"+str(a) +" TextInput 1 is required")
                break;

            if val[2] == "":
                print("row"+str(a) +" TextInput 2 is required")
                break;
            a = a+1


class Row(BoxLayout):
    button_text = StringProperty("")

    def count_row(self):
        print('count row')


class Rows(BoxLayout):
    orientation = "vertical"
    row_count = 0

    def __init__(self, **kwargs):
        super(Rows, self).__init__(**kwargs)
        self.add_row()

    def add_row(self):
        self.row_count += 1
        self.add_widget(Row(button_text=str(self.row_count)))


class test(App):

    def build(self):
        return self.root


test().run()

test.kv

<Row>:
    orientation: "horizontal"
    spacing: 0, 5

    Button:
        text: root.button_text
        size_hint_x: .2

    TextInput:
        size_hint_x: .4

    TextInput:
        size_hint_x: .4
display:

    BoxLayout:
        orientation: "vertical"
        padding : 20, 20

        BoxLayout:
            orientation: "horizontal"

            Button:
                size_hint_x: .2
                text: "+Add More"
                valign: 'bottom'
                on_press: root.add_more()


        BoxLayout:
            orientation: "horizontal"

            Label:
                size_hint_x: .2
                text: "SN"
                valign: 'bottom'

            Label:
                size_hint_x: .4
                text: "Value1"
                valign: 'bottom'
            Label:
                size_hint_x: .4
                text: "Value2"
                valign: 'bottom'

        Rows:
            id: rows


        BoxLayout:
            orientation: "horizontal"
            padding : 10, 0
            spacing: 10, 10
            size_hint: .5, .7
            pos_hint: {'x': .25, 'y':.25}

            Button:
                text: 'Ok'
                on_release:
                    root.insert()

            Button:
                text: 'Cancel'
                on_release: root.dismiss()

Upvotes: 0

Views: 1392

Answers (1)

ikolim
ikolim

Reputation: 16031

Ignore first column (value1) of every row for blank value

  1. In the kv file, remove the children TextInput widgets from the class Row.
  2. In the Python script, when instantiate the first TextInput widget, provide an id='value1'.

Please refer to the snippets below for details.

Snippets

main.py

class display(Screen):

    def add_more(self):
        self.ids.rows.add_row()

    def insert(self):

        rows = self.ids.rows

        for row in reversed(rows.children):
            for ch in reversed(row.children):
                if isinstance(ch, TextInput):
                    if ch.text == "" and ch.id != 'value1':
                        print("\nch.id=", ch.id)
                        print("TextInput is required")
                        ch.focus = True
                        break;


class Row(BoxLayout):
    button_text = StringProperty("")

    def __init__(self, **kwargs):
        super(Row, self).__init__(**kwargs)
        self.add_widget(TextInput(id="value1", size_hint_x=0.4))
        self.add_widget(TextInput(size_hint_x=0.4))

test.kv

<Row>:
    orientation: "horizontal"
    spacing: 0, 5

    Button:
        text: root.button_text
        size_hint_x: .2

Check TextInput of every row for blank value

The solution is as follow:

Snippets

class display(Screen):

    def add_more(self):
        self.ids.rows.add_row()

    def insert(self):

        rows = self.ids.rows

        for row in reversed(rows.children):
            for ch in reversed(row.children):
                if isinstance(ch, TextInput):
                    if ch.text == "":
                        print("TextInput is required")
                        ch.focus = True
                        break;

Output - Ignore first column (value1) of every row for blank value

Img01 Img02

Output - Check TextInput of every row for blank value

Img01 Img02

Upvotes: 2

Related Questions