'Getting letters in kivy from one class in another

I'm having a problem with calling my TextInputs from one class in another. I have a special class inheriting from TextInput, which makes moving with arrows possible, in my MainScreen I want to grab the letters from TextInputs and later on do something with them, however I need to pass them into this class first. I don't know how I am supposed to do that. I checked, that it's because I am unable to find any ids with id1,id2,... key, but I don't know why and how to overcome this.

.py

import kivy
import sys
kivy.require('1.11.1')
sys.path.append("c:\\users\\dom\\appdata\\local\\programs\\python\\python39\\lib\\site-packages")
from kivy.app import App
from kivy.config import Config
from kivy.core.window import Window
from kivy.uix.widget import Widget
from kivy.lang import Builder
from kivy.uix.relativelayout import RelativeLayout
from kivy.uix.gridlayout import GridLayout
from kivy.uix.screenmanager import ScreenManager, Screen
from kivy.uix.textinput import TextInput
from kivy.uix.label import Label
from kivy.app import App
from random import choice
import math
from kivy.properties import StringProperty
import string 
letters= string.ascii_lowercase
Builder.load_file("GuessWord.kv")

def set_color(letter, color):
    COLORS_DICT  = {"W" : "ffffff", "Y" : "ffff00", "G" : "00ff00"}
    c = COLORS_DICT.get(color, "W")
    return f"[color={c}]{letter}[/color]"

class MyTextInput(TextInput):   
    focused = 'id1'

    def change_focus(self, *args):
        app = App.get_running_app()
        if app.root is not None:
            # Now access the container.
            layout = app.root.ids["layout"]
            # Access the required widget and set its focus.
            print("Changefocus", MyTextInput.focused)
            layout.ids[MyTextInput.focused].focus = True

    def keyboard_on_key_down(self, window, keycode, text, modifiers):
        focusedid = int(MyTextInput.focused[2])
        if keycode[1] == "backspace":
            if self.text=="":
                if int(MyTextInput.focused[2]) > 1:
                    focusedid -= 1
                    MyTextInput.focused = "id" + str(focusedid)
            else:
                self.text = self.text[:-1]
        if keycode[1] == "right":
            if int(MyTextInput.focused[2]) < 5:
                focusedid += 1
                MyTextInput.focused = "id" + str(focusedid)
            elif int(MyTextInput.focused[2]) == 5:
                MyTextInput.focused = "id" + str(1)
                
        elif keycode[1] == "left":
            if int(MyTextInput.focused[2]) > 1:
                focusedid -= 1
                MyTextInput.focused = "id" + str(focusedid)
            elif int(MyTextInput.focused[2]) == 1:
                MyTextInput.focused = "id" + str(5)
        
        elif keycode[1] in letters:
            if int(MyTextInput.focused[2]) < 5:
                self.text=text
                focusedid += 1
                MyTextInput.focused = "id" + str(focusedid)
            
        self.change_focus()
        print("After changing", MyTextInput.focused)
        return True

        #TextInput.keyboard_on_key_down(self, window, keycode, text, modifiers)            

class MainScreen(Widget):
    def GetLetters(self):
        app = App.get_running_app()
        if app.root is not None:
            t1=app.root.ids['id1']
            t2=app.root.ids['id2']
            t3=app.root.ids['id3']
            t4=app.root.ids['id4']
            t5=app.root.ids['id5']
        listofletters=[t1,t2,t3,t4,t5]
        for letter in listofletters:
            print(letter.text)

class TestingappApp(App):
    def build(self):
        return MainScreen()
    
TestingappApp().run()

.kv

<MainScreen>:
    BoxLayout:
        size: root.size
        orientation: "vertical"
        CustomBox:
            id: layout
            cols:5
        Button:
            pos_hint: {'center_x':0.5,'y':0.67}
            size_hint: 0.5,0.1
            text: "Click here to get letters!"
            on_release: root.GetLetters()
            
            


<CustomBox@BoxLayout>:
    MyTextInput:
        id: id1
        focus: True
        focused: "id1"
        multiline: False
    MyTextInput:
        id: id2
        focused: "id2"
        multiline: False
    MyTextInput:
        id: id3
        focused: "id3"
        multiline: False
    MyTextInput:
        id: id4
        focused: "id4"
        multiline: False
    MyTextInput:
        id: id5
        focused: "id5"
        multiline: False


Solution 1:[1]

The problem is just how you are accessing the TextInput instances. Based on your kv file, the MainScreen has an id of layout for the CustomBox, and the CustomBox has ids for the TextInputs. Since the MainScreen has the id for the CustomBox, you can access it as self.ids.layout from within the MainScreen class. Once you have the CustomBox instance, you can access any of the TextInputs using the id1-id4 ids. Like this:

class MainScreen(Widget):
    def GetLetters(self):
        t1 = self.ids.layout.ids['id1']
        t2 = self.ids.layout.ids['id2']
        t3 = self.ids.layout.ids['id3']
        t4 = self.ids.layout.ids['id4']
        t5 = self.ids.layout.ids['id5']
        listofletters = [t1, t2, t3, t4, t5]
        for letter in listofletters:
            print(letter.text)

Solution 2:[2]

I'm pretty sure your issue is with app.root.ids. Last I checked, it was self.ids.NAME_OF_YOUR_ID.text to grab the text of a TextInput

Sources

This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.

Source: Stack Overflow

Solution Source
Solution 1 John Anderson
Solution 2 mohammad.alqashqish