Search code examples
pythonbindingkivyattributeerrortextinput

Kivy Binding Textinput to Submit Button gives AttributeError: 'NoneType' object has no attribute 'text'


I'm trying to build a small application for my thesis and after I made the basic Layout, I tried to bind some actions. Right now I'm struggeling with saving some TextInputs by pressing a submit button. The issue might be that I created the TextInput Grid in a different .kv-file than the .kv-file where my StatusBar with the buttons 'Submit' and 'Clear' are. For the beginning i was just trying to print the TextInput in my console when pressing 'Submit'. I hope you can help me, I think i shouldn't be too hard and I#M just mising something eay due to a lock of programming experience.

So here's my main python file:

import kivy
from kivy.app import App
from kivy.uix.button import Label
from kivy.uix.widget import Widget
from kivy.uix.textinput import TextInput
from kivy.lang import Builder
from kivy.uix.anchorlayout import AnchorLayout
from kivy.uix.boxlayout import BoxLayout
from kivy.properties import ObjectProperty

Builder.load_file('Header.kv')
Builder.load_file('Statusbar.kv')
Builder.load_file('Inputparameters.kv')
Builder.load_file('Outputparameters.kv')

class Peenomat(AnchorLayout):
    pass

class PeenomatApp(App):
    def build(self):
        return Peenomat()

if __name__=="__main__":
    PeenomatApp().run()

my main Kivy file

<Peenomat>

    AnchorLayout:
        anchor_x: 'left'
        anchor_y: 'bottom'
        GridLayout:
            cols: 1

            canvas.before:
                Color:
                    rgba: 0.75 ,0.75, 0.75, 1
                Rectangle:
                    pos: self.pos
                    size: self.size

            Header:
                id: _header
                size_hint: 1, 0.1
                #height: 100

            InputParameters:
                id:_input_parameters
                size_hint: 1, 0.45
                #height: root.height - _status_bar.height #-_header.height

            StatusBar:
                id:_status_bar
                size_hint: 1, 0.1
                #height: 50

            OutputParameters:
                id:_output_parameters
                size_hint: 1, 0.35

the field where I enter the necessary text, everythinf assigned with id's

<InputParameters@GridLayout>

    prozess: _prozess
    material: _material
    haerte: _haerte
    rauheit: _rauheit

    cols: 2
    padding: 15

    #Prozess
    Label:
        text:'Prozess:'

    TextInput:
        id: _prozess
        hint_text:'Text'
        multiline: False

    #Material
    Label:
        text:'Material:'

    TextInput:
        id: _material
        hint_text:'Text'
        multiline: False

    # Haerte
    Label:
        text:'Haerte:'

    TextInput:
        id: _haerte
        hint_text:'Text'
        multiline: False

    # Rauheit
    Label:
        text:'Rauheit:'

    TextInput:
        id: _rauheit
        hint_text:'Text'
        multiline: False

and my StatusBar that includes the Buttons:

#: import statusbar StatusBar

<StatusBar@BoxLayout>

    orientation:'horizontal'
    padding: 5
    fs: 16
    Button:
        text: 'Clear'
        background_color: 0.0, 0.353, 0.663, 1.0
        size_hint: 0.4, 1
        font_size: 20

    Button:
        text: 'Submit'
        background_color: 0.0, 0.353, 0.663, 1.0
        size_hint: 0.4, 1
        font_size: 20
        on_press: root.btn_submit()

the imported py.-file that statusbar uses for the button method that should print the textinput is the following:

from kivy.uix.boxlayout import BoxLayout
from kivy.properties import ObjectProperty

class StatusBar(BoxLayout):
    group_mode = False
    #translation = ListProperty(None)
    prozess = ObjectProperty(None)
    material = ObjectProperty(None)
    haerte = ObjectProperty(None)
    rauheit = ObjectProperty(None)

    def btn_submit(self):
        print("Prozess:", self.prozess.text, "Material:", self.material.text)

There exist 2 more .kv-files that are mentioned in the main.py, but i don't think they#re necessary for that issue. The App works and pops up if I run it, but once I add some text and hit my 'Submit' Button I get the error: "AttributeError: 'NoneType' abject has no attribute 'text'"

I know the the seperate files might be the issue and confusing, but cause this is only the start of the app and the code will get bigger I wanna keep it that way. I really hope you can help me 'cause I'm devestated... Thank you!


Solution

  • The problem is that your code:

    print("Prozess:", self.prozess.text, "Material:", self.material.text)
    

    is referencing prozess and material as though they are attributes of the StatusBar class, but they are actually attributes of the InputParameters class.

    I haven't tested this, but you should be replace your btn_submit() with something like:

    def btn_submit(self):
        ip = App.get_running_app().root.ids._input_parameters
        print("Prozess:", ip.prozess.text, "Material:", ip.material.text)
    

    Again, I have not tested this code, but something like it should work.