pythonandroidkivyids

I can't make references and search for IDs in a specific window, using the screenmanager, Python / Kivy


I am developing an application in Python and with the kivy library. In the past version of the App, it had only one window, and the code worked well, however, I need to implement multi-windows, and the problem is that I can't reference the ids inside the windows I created.

main.py

from kivy.app import App
from kivy.core.window import Window
from kivy.uix.popup import Popup
from kivy.uix.label import Label
from kivy.properties import ObjectProperty, ListProperty
from kivy.uix.image import Image
from kivy.uix.screenmanager import ScreenManager, Screen
from kivy.lang import Builder
from kivy.uix.widget import Widget

#-----------------------------------------------------------------------------------------------------------------------

Window.softinput_mode = 'below_target'
Window.clearcolor = [1, 1, 0.9, 0.9]

class FirstWindow(Screen):
    pass

class SecondWindow(Screen):
    pass

class ThirdWindow(Screen):
    pass

class WindowManager(ScreenManager):
    pass

class CustomPopup(Popup):
    pass

class MainApp(App):
    texture = ObjectProperty()

    def open_popup(self):
        the_popup = CustomPopup()
        the_popup.open()

    def build(self):
        self.title = 'Myapp'
        self.texture = Image(source = 'wave.png').texture


#        self.first_window.ids.x.text
#        self.screen_manager = ScreenManager()
#        self.FirstWindow = FirstWindow()
#        screen = Screen(name = 'first')
#        screen.add_widget(self.FirstWindow)
#        self.screen_manager.add_widget(screen)
#        primeiro = self.screen_manager.get_screen("first")
        
    def calcular(self, *args):

#>>>>> The problem happens here, I believe that the code can no longer get the data from the ids because
  they are no longer in root. and I don't know how to reference them. The problem didn't happen before
 because the kivy code had only one window <<<<<<<<<<<

        s_x = self.root.ids.x.text
        s_y = self.root.ids.y.text
        s_z = self.root.ids.z.text
        s_rpa = self.root.ids.rpa.text
        s_rt = self.root.ids.rt.text
        s_rpi = self.root.ids.rpi.text
        s_t = self.root.ids.t.text
        s_ii = self.root.ids.ii.text
        s_ie = self.root.ids.ie.text
        s_ac = self.root.ids.ac.text

#-----------------------------------------------------------------------------------------------------------------------

        # Conditionals and variables:

        if (s_x == ''):
            s_x = 6
        if (s_y == ''):
            s_y = 6
        if (s_z == ''):
            s_z = 3
        if (s_ie == ''):
            s_ie = 20000
        if (s_ii == ''):
            s_ii = 300
        if (s_t == ''):
            s_t = 0.88
        if (s_rpi == ''):
            s_rpi = 0.3
        if (s_rt == ''):
            s_rt = 0.7
        if (s_rpa == ''):
            s_rpa = 0.5
        if (s_ac == ''):
            s_ac = 90

        x = float(s_x)
        y = float(s_y)
        z = float(s_z)
        rpi = float(s_rpi)
        rt = float(s_rt)
        rpa = float(s_rpa)
        t = float(s_t)
        ac = float(s_ac)
        ii = float(s_ii)
        ie = float(s_ie)

#-----------------------------------------------------------------------------------------------------------------------

        # Equacions:

        apa = 2*((x*z)+(y*z))
        api = x * y
        at = x * y
        a = apa + api + at
        r = ((rpa * apa) + (rpi * api) + (rt * at)) / a
        fld = (ii/ie)*100
        w = (fld*a*(1-(r ** 2))) / (t*ac)
        w = round(w, 2)
        w = str(w)
        w = w.replace(".", ",")
        w = w +" m²"
        print(w)

#-----------------------------------------------------------------------------------------------------------------------
# >>>>>>>>The problem with ids also happens here <<<<<<<<<<

        # Button calculate:

        if (( t<=0 or t>1 ) or ( rpa<=0 or rpa>=1 ) or ( rpi<=0 or rpi >=1 ) or ( rt<=0 or rt>=1 ) or (ac<=0 or ac>180)):
            the_popup = Popup(title='Erro', content=Label(id='_result', text='Valor fornecido invalido.'),size_hint=(.5, .2), separator_color=[1, 1, 0.6, 0.8])
            the_popup.open()
        else:
            self.root.ids.resultado.text = w
            self.root.ids.resultado.opacity = 1

        if (ac > 90):
            self.root.ids.tipojanela.text = 'Janela azimutal'
            self.root.ids.tipojanela.opacity = 1
        else:
            self.root.ids.tipojanela.opacity = 0

#-----------------------------------------------------------------------------------------------------------------------

def exit(self):
        App.get_running_app().stop()

aplicativo = MainApp()
aplicativo.run()

main.kv

<Button>:
    background_down: ''

<CustomPopup>:
    size_hint: 1,.7
    auto_dismiss: False
    title: 'Ajuda'
    separator_color:  1,1,0.6,0.8

    FloatLayout:
        id: primeiro_float
        Label:
            text: '- O valor para a transmitância deve ser maior que 0 e menor ou igual a 1 \n - Os valores para as refletâncias devem estar entre 0 e 1 \n - O ângulo de céu visível deve ser maior que 0° e menor ou igual a 180°"'
            font_size: 25
            text_size: self.size
            halign: 'center'
            valign: 'middle'
            size: primeiro_float.size
            pos: primeiro_float.pos

        Button:
            size_hint: None, None
            width: self.texture_size[0] - dp(10)
            height: self.texture_size[0] - dp(10)
            pos_hint: {'center_x': .5, 'y': .05}
            halign:'right'
            valign: 'top'
            text: 'fechar'
            color: 0,0,0,0
            border: 0,0,0,0
            background_normal: 'close.png'
            background_down: 'close.png'
            on_press: root.dismiss()

WindowManager:
    FirstWindow:
    SecondWindow:
    ThirdWindow:

<FirstWindow>:
    name: 'first'
    id: first_window
    FloatLayout:
        canvas:
            Rectangle:
                pos: self.pos
                size: self.size
                texture: app.texture
        GridLayout:
            cols:1
            ActionBar:
                background_color: 1,1,1,1
                background_image: ''
                ActionView:
                    use_separator: True
                    ActionPrevious:
                        background_image:''
                        background_down: ''
                        background_normal: ''
                        background_color: ''
                        source: ''
                        app_icon: 'fld.png'
                        previous_image: ''
                        color: 0,0,0,1
                    ActionGroup:
                        background_normal: 'list1.png'
                        background_down: 'list2.png'
                        source:''
                        mode: 'spinner'
                        size_hint: None, None
                        width: '50sp'
                        height: '50sp'
                        border: 0,0,0,0
                        ActionButton:
                            background_color: 0.3,1,0.6,1
                            source:''
                            text: 'Ajuda'
                            on_press: app.open_popup()
                            id:ajuda
                        ActionButton:
                            background_color: 0.3,1,0.6,1
                            background_normal: ''
                            text: 'Sair'
                            id:sair
                            on_release: app.exit()

            Label:
                canvas.before:
                    Color:
                        rgba: 1,1,0.6,0.8
                    Rectangle:
                        pos: self.pos
                        size: self.size
                color: 0,0,0,1
                size_hint_y: None
                height: self.font_size + dp(10)
                text: 'Ambiente'
                halign: 'center'
                valign: 'middle'

            GridLayout:
                size_hint: None, None
                width: root.width
                height: self.minimum_height
                padding: 10, 10, 10, 10
                spacing: dp(10)
                cols:4
                
                Label:
                    text: 'Comprimento (m)'
                    color: 0.5,0.5,0.5,1
                    text_size: self.size
                    font_size: '11sp'
                    halign: 'center'
                    valign: 'middle'
                    size_hint_y: None
                    height: self.font_size + dp(20)
                TextInput:
                    text: '6'
                    id: x
                    cursor_color: 0,0,0,1
                    size_hint_y: None
                    height: self.font_size + dp(15)
                    input_filter:'float'
                    multiline: False
                    write_tab: False
                    on_text_validate: y.focus = True

                Label:
                    text: 'Refletância do piso ]0;1['
                    color: 0.5,0.5,0.5,1
                    text_size: self.size
                    font_size: '11sp'
                    halign: 'center'
                    valign: 'middle'
                    size_hint_y: None
                    height: self.font_size + dp(20)
                TextInput:
                    text: '0.3'
                    id: rpi
                    cursor_color: 0,0,0,1
                    input_filter:'float'
                    multiline: False
                    write_tab: False
                    on_text_validate: rt.focus = True

                Label:
                    text: 'Largura (m)'
                    color: 0.5,0.5,0.5,1
                    text_size: self.size
                    font_size:'11sp'
                    halign: 'center'
                    valign: 'middle'
                    size_hint_y: None
                    height: self.font_size + dp(20)
                TextInput:
                    text: '6'
                    id: y
                    cursor_color: 0,0,0,1
                    input_filter:'float'
                    multiline: False
                    write_tab: False
                    on_text_validate: z.focus = True

                Label:
                    text: 'Refletância do teto ]0;1['
                    color: 0.5,0.5,0.5,1
                    text_size: self.size
                    font_size: '11sp'
                    halign: 'center'
                    valign: 'middle'
                    size_hint_y: None
                    height: self.font_size + dp(20)
                TextInput:
                    text: '0.7'
                    id: rt
                    cursor_color: 0,0,0,1
                    multiline: False
                    input_filter:'float'
                    multiline: False
                    write_tab: False
                    on_text_validate: rpa.focus = True

                Label:
                    text: 'Pé-direito (m)'
                    color: 0.5,0.5,0.5,1
                    text_size: self.size
                    font_size: '11sp'
                    halign: 'center'
                    valign: 'middle'
                    size_hint_y: None
                    height: self.font_size + dp(20)
                TextInput:
                    text: '3'
                    id: z
                    cursor_color: 0,0,0,1
                    input_filter:'float'
                    multiline: False
                    write_tab: False
                    on_text_validate: rpi.focus = True

                Label:
                    text: 'Refletância das paredes ]0;1['
                    color: 0.5,0.5,0.5,1
                    text_size: self.size
                    font_size: '11sp'
                    halign: 'center'
                    valign: 'middle'
                    size_hint_y: None
                    height: self.font_size + dp(20)
                    on_text_validate:
                TextInput:
                    text: '0.5'
                    id: rpa
                    cursor_color: 0,0,0,1
                    input_filter:'float'
                    multiline: False
                    write_tab: False
                    on_text_validate: t.focus = True

            Label:
                canvas.before:
                    Color:
                        rgba: 1,1,0.6,0.8
                    Rectangle:
                        pos: self.pos
                        size: self.size
                color: 0,0,0,1
                size_hint_y: None
                height: self.font_size + dp(10)
                text: 'Abertura'
                halign: 'center'
                valign: 'middle'

            GridLayout:
                size_hint: None, None
                width: root.width
                height: self.minimum_height
                padding: 10, 10, 10, 10
                spacing: dp(10)
                cols:2

                Label:
                    text: 'Transmitância ]0;1]'
                    color: 0.5,0.5,0.5,1
                    text_size: self.size
                    font_size: '11sp'
                    halign: 'center'
                    valign: 'middle'
                    size_hint_y: None
                    height: self.font_size + dp(20)
                TextInput:
                    text: '0.88'
                    id: t
                    cursor_color: 0,0,0,1
                    input_filter:'float'
                    multiline: False
                    write_tab: False
                    on_text_validate: ac.focus = True

            Label:
                canvas.before:
                    Color:
                        rgba: 1,1,0.6,0.8
                    Rectangle:
                        pos: self.pos
                        size: self.size
                color: 0,0,0,1
                size_hint_y: None
                height: self.font_size + dp(10)
                text: 'Obstrução'
                halign: 'center'
                valign: 'middle'

            GridLayout:
                size_hint: None, None
                width: root.width
                height: self.minimum_height
                padding: 10, 10, 10, 10
                spacing: dp(10)
                cols:2

                Label:
                    text: 'Ângulo de céu visível (°)'
                    color: 0.5,0.5,0.5,1
                    text_size: self.size
                    font_size: '11sp'
                    halign: 'center'
                    valign: 'middle'
                    size_hint_y: None
                    height: self.font_size + dp(20)
                TextInput:
                    text: '90'
                    id: ac
                    cursor_color: 0,0,0,1
                    multiline: False
                    write_tab: False
                    input_filter:'float'
                    on_text_validate: ie.focus = True

            Label:
                canvas.before:
                    Color:
                        rgba: 1,1,0.6,0.8
                    Rectangle:
                        pos: self.pos
                        size: self.size
                color: 0,0,0,1
                size_hint_y: None
                height: self.font_size + dp(10)
                text: 'Iluminâncias'
                halign: 'center'
                valign: 'middle'

            GridLayout:
                size_hint: None, None
                width: root.width
                height: self.minimum_height
                padding: 10, 10, 10, 10
                spacing: dp(10)
                cols:2

                Label:
                    text: 'Iluminância externa difusa (lx)'
                    color: 0.5,0.5,0.5,1
                    text_size: self.size
                    font_size: '11sp'
                    halign: 'center'
                    valign: 'middle'
                    size_hint_y: None
                    height: self.font_size +dp(20)
                TextInput:
                    text: '20000'
                    id: ie
                    cursor_color: 0,0,0,1
                    multiline: False
                    write_tab: False
                    input_filter: 'float'
                    on_text_validate: ii.focus = True

                Label:
                    text: 'Iluminância interna média no Plano de Trabalho (lx)'
                    color: 0.5,0.5,0.5,1
                    text_size: self.size
                    font_size: '11sp'
                    halign: 'center'
                    valign: 'middle'
                    size_hint_y: None
                    height: self.font_size +dp(20)
                TextInput:
                    text: '300'
                    id: ii
                    cursor_color: 0,0,0,1
                    multiline: False
                    write_tab: False
                    input_filter: 'float'
                    on_text_validate: bt.focus = True

            FloatLayout:
                Button:
                    pos_hint: {'center_x': .5, 'center_y': .6}
                    width: '220sp'
                    height: '45sp'
                    size_hint: None, None
                    color: 0,0,0,1
                    background_normal: 'calcu1.png'
                    background_down: 'calcu2.png'
                    #background_color: 1,1,0.9,0.9
                    border: 0,0,0,0
                    id: bt
                    text: u'Calcular a área da janela'
                    font_size: '17sp'
                    on_release: app.calcular()

            FloatLayout:
                Label:
                    text: 'v1.0.3 - Beta'
                    pos_hint: {'center_x': 0.85, 'center_y': .2}
                    color: 0,0,0,1
                    font_size: '14sp'

                Button:
                    size_hint: None, None
                    width: '25sp'
                    height: '25sp'
                    pos_hint: {'center_x': .94, 'y': .4}
                    #halign:'right'
                    #valign: 'top'
                    border: 0,0,0,0
                    background_normal: 'int1.png'
                    background_down: 'int2.png'
                    on_release:
                        app.root.current = 'second'
                        root.manager.transition.direction = 'left'

                Button:
                    size_hint: None, None
                    width: '25sp'
                    height: '25sp'
                    pos_hint: {'center_x': .94, 'y': .9}
                    #halign:'right'
                    #valign: 'top'
                    border: 0,0,0,0
                    background_normal: 'cont.png'
                    background_down: 'cont.png'
                    on_release:
                        app.root.current = 'third'
                        root.manager.transition.direction = 'left'


                Label:
                    id: resultado
                    opacity: 0
                    pos_hint: {'center_x': .5, 'center_y': .9}
                    width: self.texture_size[0] + dp(20)
                    size_hint_x: None
                    size_hint_y: .4
                    text: ''
                    color: 0,0,0,1
                    canvas.before:
                        Color:
                            rgba: 1,1,0.6,0.8
                        RoundedRectangle:
                            radius:{(10.0,), (10.0,), (10.0,), (10.0,)}
                            size: self.size
                            pos: self.pos
                Label:
                    id: tipojanela
                    opacity: 0
                    pos_hint: {'center_x': .5, 'center_y': .35}
                    width: self.texture_size[0] + dp(20)
                    size_hint_x: None
                    size_hint_y: .4
                    text: ''
                    color: 0,0,0,1
                    canvas.before:
                        Color:
                            rgba: 1,1,0.6,0.8
                        RoundedRectangle:
                            radius:{(10.0,), (10.0,), (10.0,), (10.0,)}
                            size: self.size
                            pos: self.pos

<SecondWindow>:
    name: 'second'
    id: second_window

    BoxLayout:
        orientation: 'vertical'
        size: root.width, root.height
        Label:
            text: 'Segunda janela'
            font_size: 32
        Button:
            text: 'Voltar pra primeira janela'
            font_size: 32
            on_release:
                app.root.current = 'first'
                root.manager.transition.direction = 'right'

<ThirdWindow>:
    name: 'third'
    id: second_window

    BoxLayout:
        orientation: 'vertical'
        size: root.width, root.height
        Label:
            text: 'terceira janela'
            font_size: 32
        Button:
            text: 'Voltar pra primeira janela'
            font_size: 32
            on_release:
                app.root.current = 'first'
                root.manager.transition.direction = 'right'

Error on:

 on_release: app.calcular()

Error:

File "C:\Users\Gilson Carvalho\Desktop\TropWin 01-04-2021\Arriscando Tudo 2\main.py", line 63, in calcular
  s_x = self.root.ids.x.text
File "kivy\properties.pyx", line 864, in kivy.properties.ObservableDict.__getattr__
AttributeError: 'super' object has no attribute '__getattr__'

Could anyone help me with this?


Solution

  • You are correct, the ids are no longer in self.root, because that is now the ScreenManager (WindowManager). The way to access those ids now is through the get_screen() method of ScreenManager. For example, replace:

    s_x = self.root.ids.x.text
    

    with:

    s_x = self.root.get_screen('first').ids.x.text