Issue
So, I wanted to create an app that created tasks/habits in kivy. Basically, there would be a screen that shows you your tasks/habits, and you could click on a button to take you to another screen to create a new task/habit. You would input information about the task/habit in that screen, and click the submit button. The submit button would add the task/habit to the first screen. However, when I run my code, it works the first time. I can go to the second screen, add my habit/code and then go back to the first screen. However, when I click the button on the first screen, it gives me an error.
The error being: kivy.uix.screenmanager.ScreenManagerException: No Screen with name "second".
Here is my code:
main.py:
from kivy.lang import Builder
from kivy.properties import ObjectProperty
from kivy.uix.boxlayout import BoxLayout
from kivy.uix.gridlayout import GridLayout
from kivy.uix.label import Label
from kivy.uix.widget import Widget
from kivy.app import App
from kivy.uix.screenmanager import ScreenManager, Screen
from kivy.uix.image import Image
from PIL import Image
import numpy as np
class FirstWindow(Screen):
def add_label(self, name, time, date):
label = Label(text= f' {name}, {time}, {date}')
self.ids.boxlayout.add_widget(label)
class SecondWindow(Screen):
a_task = False
a_habit = False
name = ""
time = ""
date = ""
def task_button(self):
self.a_task = True
self.a_habit = False
def habit_button(self):
self.a_habit = True
self.a_task = False
def submit_button(self):
self.name = self.ids.the_name.text
self.time = f'{self.ids.time_spinner_1.text}:{self.ids.time_spinner_2.text}'
self.date = f'{self.ids.date_spinner_1.text}/{self.ids.date_spinner_2.text}'
def get_name(self):
return self.name
def get_time(self):
return self.time
def get_date(self):
return self.date
kv = Builder.load_file('Button.kv')
class ButtonApp(App):
def build(self):
sm = ScreenManager()
sm.add_widget(FirstWindow())
sm.add_widget(SecondWindow())
return sm
if __name__ == '__main__':
ButtonApp().run()
Button.kv:
<FirstWindow>:
name: "first"
BoxLayout:
id: boxlayout
orientation: "vertical"
canvas.before:
Color:
rgba: (0.3,0.33,0.3,1)
Rectangle:
pos: self.pos
size: self.size
FloatLayout:
Label:
text: "To Do List"
font_size: 32
pos_hint: { 'right': 0.65, 'top': 1.4 }
Button:
text: "add a task"
on_release: root.manager.current = "second"
<SecondWindow>:
name: "second"
BoxLayout:
orientation: "vertical"
spacing: "10dp"
canvas.before:
Color:
rgba: (0.3,0.33,0.3,1)
Rectangle:
pos: self.pos
size: self.size
FloatLayout:
Label:
text: "Add A Task"
font_size: 32
pos_hint: { 'right': 0.65, 'top': 1.2 }
BoxLayout:
orientation: "horizontal"
Button:
text: "task"
on_press: root.task_button()
Button:
text: "habit"
on_press: root.habit_button()
TextInput:
id: the_name
text: "Name"
Label:
text: "alert"
BoxLayout:
orientation: "horizontal"
Spinner:
id: time_spinner_1
text: "00"
values: ['1','2','3','4','5','6','7','8','9','10','11', '12']
Spinner:
id: time_spinner_2
text: "00"
values: ['01','02','03','04','05','06','07','08','09','10','11', '12', '13','14','15','16','17','18','19','20','21','22','23','24','25','26','27','28','29','30','31','32','33','34','35','36','37','38','39','40','41','42','43','44','45','46','47','48','49','50','51','52','53','54','55','56','57','58','59']
BoxLayout:
orientation: "horizontal"
Spinner:
id: date_spinner_1
text: "00"
values: ['1','2','3','4','5','6','7','8','9','10','11', '12']
Spinner:
id: date_spinner_2
text: "00"
values: ['01','02','03','04','05','06','07','08','09','10','11', '12', '13','14','15','16','17','18','19','20','21','22','23','24','25','26','27','28','29','30','31']
Button:
text: "submit"
on_press: root.submit_button()
on_release:
root.manager.current = "first"
root.manager.get_screen("first").add_label(root.get_name(), root.get_time(), root.get_date())
Solution
Your code:
def submit_button(self):
self.name = self.ids.the_name.text
self.time = f'{self.ids.time_spinner_1.text}:{self.ids.time_spinner_2.text}'
self.date = f'{self.ids.date_spinner_1.text}/{self.ids.date_spinner_2.text}'
changes the name
property of the SecondWindow
Screen
, so trying to change Screen
to the second
will no longer work. It looks like you are trying to use name
for some other purpose. I suggest you use a variable with a different name.
Answered By - John Anderson
Answer Checked By - Pedro (JavaFixing Volunteer)