I'm trying to program a simple test app where
I have a .py file with the python script where you have the "submit" function, which is supposed to send the email address to the online ElephantSQL database, and finally give a "thank you" message once it's done. It seems like I'm doing something wrong as I get an error which tells me the below:
Traceback (most recent call last):
File "C:\Users\User\Documents\Pers\Python\test\test.py", line 99, in <module>
Yes().run()
File "C:\Users\User\AppData\Local\Programs\Python\Python39\lib\site-packages\kivy\app.py", line 955, in run
runTouchApp()
File "C:\Users\User\AppData\Local\Programs\Python\Python39\lib\site-packages\kivy\base.py", line 574, in runTouchApp
EventLoop.mainloop()
File "C:\Users\User\AppData\Local\Programs\Python\Python39\lib\site-packages\kivy\base.py", line 339, in mainloop
self.idle()
File "C:\Users\User\AppData\Local\Programs\Python\Python39\lib\site-packages\kivy\base.py", line 383, in idle
self.dispatch_input()
File "C:\Users\User\AppData\Local\Programs\Python\Python39\lib\site-packages\kivy\base.py", line 334, in dispatch_input
post_dispatch_input(*pop(0))
File "C:\Users\User\AppData\Local\Programs\Python\Python39\lib\site-packages\kivy\base.py", line 302, in post_dispatch_input
wid.dispatch('on_touch_up', me)
File "kivy\_event.pyx", line 731, in kivy._event.EventDispatcher.dispatch
File "C:\Users\User\AppData\Local\Programs\Python\Python39\lib\site-packages\kivy\uix\behaviors\button.py", line 179, in on_touch_up
self.dispatch('on_release')
File "kivy\_event.pyx", line 727, in kivy._event.EventDispatcher.dispatch
File "kivy\_event.pyx", line 1307, in kivy._event.EventObservers.dispatch
File "kivy\_event.pyx", line 1191, in kivy._event.EventObservers._dispatch
File "C:\Users\User\AppData\Local\Programs\Python\Python39\lib\site-packages\kivy\lang\builder.py", line 55, in custom_callback
exec(__kvlang__.co_value, idmap)
File "C:\Users\User\Documents\Pers\Python\test\Test.kv", line 77, in <module>
on_release: app.submit()
File "C:\Users\User\Documents\Pers\Python\test\test.py", line 87, in submit
'first': kv.input_box.text,
AttributeError: 'WindowManager' object has no attribute 'input_box'
Below are both the scripts from my .py file and my .kv file
My test.py file:
from kivy.app import App
from kivy.uix.gridlayout import GridLayoutException
from kivy.uix.label import Label
from kivy.uix.image import Image
from kivy.uix.button import Button
from kivy.uix.textinput import TextInput
from kivy.uix.widget import Widget
from kivy.lang import Builder
from kivy.uix.screenmanager import ScreenManager, Screen
import os
import urllib.parse as up
import psycopg2
#define our different windows (hence our different pages in our app)
class FirstWindow(Screen):
pass
class SecondWindow(Screen):
pass
#define our screen manager (hence what manages the different pages in our app)
class WindowManager(ScreenManager):
pass
# designate our .kv design file
kv = Builder.load_file('Test.kv')
class Yes(App):
def build(self):
url = up.urlparse("DBURL")
# connect to the database
conn = psycopg2.connect("dbname='DBNAME' user='DBUSER' host='DBHOST' password='DBPWD'")
# create the database cursor
cur = conn.cursor()
# insert the query to create the table (if not yet
# created) in which the data (email addresses
# will be stored)
cur.execute("CREATE TABLE if not exists emails(id INTEGER PRIMARY KEY, address text)")
# commit changes
conn.commit()
# close the connection to the database
conn.close()
return kv
# define our submit function, i.e. the function which will be
# triggered when we click to send the email address to be
# stored in the database
def submit(self):
# database URL
url = up.urlparse("DBURL")
# connect to the database
conn = psycopg2.connect("dbname='DBNAME' user='DBUSER' host='DBHOST' password='DBPWD'")
# create the database cursor
cur = conn.cursor()
# insert the query to submit the data,
# i.e. email addresses to the database
psycopg_command = "INSERT INTO emails (address) VALUES (%s)"
values = (kv.get_screen('second').ids.input_box.text,)
cur.execute(psycopg_command, values)
# add message to user once email address has been submitted
kv.get_screen('second').ids.input_box.text = "Thanks for submitting your email address"
# clear the input box once the email address has been submitted
'''kv.get_screen('second').ids.input_box.text = ""'''
# commit changes
conn.commit()
# close the connection to the database
conn.close()
if __name__ == '__main__':
Yes().run()
My test.kv file:
#:import NoTransition kivy.uix.screenmanager.NoTransition
WindowManager:
FirstWindow:
SecondWindow:
<FirstWindow>:
name: "first"
BoxLayout:
orientation: "vertical"
size: root.width, root.height
Label:
text: "Hi"
font_size: 32
Button:
text: "Next"
size_hint: 0.3, 0.3
pos_hint: {"center_x":0.5}
background_color: 0.06666666666, 0.82352941176, 0.90980392156, 1
background_normal: ""
on_release:
app.root.current = "second"
root.manager.transition.direction = "left"
Widget:
size_hint: 0.3, None
height: 6
canvas:
Color:
rgb: 0, 0, 0, 1
<SecondWindow>:
name: "second"
BoxLayout:
orientation: "vertical"
size: root.width, root.height
Label:
id: word_label
text: "Enter your email address"
font_size: 32
Widget:
size_hint: 0.3, None
height: 6
canvas:
Color:
rgb: 0, 0, 0, 1
TextInput:
id: input_box
size_hint: (0.3, 0.2)
pos_hint: {"center_x":0.5}
multiline: False
valign: "center"
halign: "center"
text:""
Widget:
size_hint: 0.3, None
height: 6
canvas:
Color:
rgb: 0, 0, 0, 1
Button:
text: "Validate"
size_hint: 0.3, 0.3
pos_hint: {"center_x":0.5}
background_color: 0.06666666666, 0.82352941176, 0.90980392156, 1
background_normal: ""
on_release: app.submit()
Widget:
size_hint: 0.3, None
height: 6
canvas:
Color:
rgb: 0, 0, 0, 1
Button:
text: "Home"
size_hint: 0.3, 0.3
pos_hint: {"center_x":0.5}
background_color: 0.06666666666, 0.82352941176, 0.90980392156, 1
background_normal: ""
on_release:
app.root.current = "first"
root.manager.transition = NoTransition()
Widget:
size_hint: 0.3, None
height: 6
canvas:
Color:
rgb: 0, 0, 0, 1
I understand that it says my "WindowsManager" doesn't have the attribute "input_box", but I'm clueless as to what to do to solve the issue. I tried some tweaks, but I won't overcharge the content of my question and leave it at asking: How to solve my mistake?
Thks
So your variable named kv
is a reference to your WindowManager
, which is an instance of ScreenManager
. You can use the get_screen()
method of ScreenManager
(see the docs) to access the Screen
that contains the TextInput
that you want to update. So, try changing:
kv.input_box.text = "Thanks"
to:
kv.get_screen('second').ids.input_box.text = "Thanks"
Also note that if your set the text
of a TextInput
, then immediately clear that text
, then you will never see the first text
.