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?
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