Why is my navigation code not working? kivy python - python

I have a screen manager ThirdWindow which is supposed to change the screen when B1 is clicked basically a navigation thing. Please note ThirdWindow is a a different class. callback is called when B1 is clicked. it changes the screen with the help of ThirdWindow I think. I used self.manager.current it didn't worked, I also tried using it by making ThirdWindow a def in class Dre but the results were same. The print statement is not getting printed that is inside def callback(self, instance) so I think the def is not getting called on_click at all. How can I fix that? Thanks
import kivy
from kivy.app import App
from kivy.core.audio import SoundLoader
from kivy.uix.gridlayout import GridLayout
from kivy.uix.label import Label
from kivy.uix.textinput import TextInput
from kivy.uix.button import Button
from kivy.uix.stacklayout import StackLayout
from kivy.uix.relativelayout import RelativeLayout
from kivy.graphics import Rectangle
from kivy import platform
from kivy.lang import Builder
from kivy.uix.screenmanager import ScreenManager, Screen
class MainWindow(Screen):
pass
class ThirdWindow(ScreenManager):
def load(self):
sm = ScreenManager
sm.add_widget(Dre(name='Dre'))
sm.add_widget(SecondWindow(name='SecondWindow'))
self.sm.current = 'Dre'
class Dre(RelativeLayout):
def __init__(self, **kwargs):
super(Dre, self).__init__(**kwargs)
self.color = [254/255, 102/255, 37/255, 1]
self.H_color = [254/255, 102/255, 37/255]
self.sound_theme = None
self.init_audio()
self.kv = Builder.load_file('Levels.py')
if platform in ('linux', 'win', 'macosx'):
with self.canvas.before:
self.bg = Rectangle(size=self.size, source='Neo.png')
self.bind(pos=self.update_bg)
self.bind(size=self.update_bg)
else:
with self.canvas.before:
self.bg = Rectangle(size=self.size, source='Neon.png')
self.bind(pos=self.update_bg)
self.bind(size=self.update_bg)
def update_bg(self, *args):
if platform in ('linux', 'win', 'macosx'):
self.bg.pos = self.pos
self.bg.size = self.size
self.add_widget(Label(text='D R E A M S',
pos_hint={'center_x': .5, 'center_y': .8},
font_size='60dp', font_name='Roboto-Bold.ttf', color=self.H_color))
B1 = Button(text='P L A Y', font_name='Roboto-Bold.ttf', size_hint=(.2, .15),
pos_hint={'center_x': .5, "center_y": .3}, background_color = self.color, background_normal='')
# B1.bind(on_press=return self.kv)
self.add_widget(B1)
else:
self.bg.pos = self.pos
self.bg.size = self.size
self.add_widget(Label(text='D R E A M S',
pos_hint={'center_x': .5, 'center_y': .8},
font_size='30dp', font_name='Roboto-Bold.ttf', color=self.H_color))
B1 = Button(text='P L A Y', font_name='Roboto-Bold.ttf', size_hint=(.2, .15),
pos_hint={'center_x': .5, "center_y": .3}, background_color=self.color, background_normal='',
on_press=self.callback)
self.add_widget(B1)
def callback(self, instance):
print('working')
self.manager.current = 'SecondWindow'
def init_audio(self):
self.sound_theme = SoundLoader.load('Bg_theme.mp3')
self.sound_theme.volume = 1
self.sound_theme.loop = True
if self.sound_theme:
self.sound_theme.play()
print('okay')
else:
print('not okay')
class SecondWindow(Screen):
def __init__(self, **kwargs):
super(SecondWindow, self).__init__(**kwargs)
self.color = [254 / 255, 102 / 255, 37 / 255, 1]
if platform in ('linux', 'win', 'macosx'):
with self.canvas.before:
self.bg = Rectangle(size=self.size, color=self.color)
class LabApp(App):
def build(self):
return Dre()
if __name__ == '__main__':
LabApp().run()```
if you provide any solution please provide it in .py file.

Many issues with your code.
First, you have defined a ScreenManager class (ThirdWindow), but you have not created an instance of it or included it in your GUI. In order to use a ScreenManager to manage Screens, you must add it to your GUI. I would suggest modifying your LabApp class to use ThirdWindow:
class LabApp(App):
def build(self):
return ThirdWindow()
and modify ThirdWindow to replace the load() method with an __init__() method:
class ThirdWindow(ScreenManager):
def __init__(self, **kwargs):
super(ThirdWindow, self).__init__(**kwargs)
self.add_widget(Dre(name='Dre'))
self.add_widget(SecondWindow(name='SecondWindow'))
Since the Dre class is being used as a Screen, it must be redefined as a Screen:
class Dre(Screen):
and you can add the callback to the creation of the B1 Button:
B1 = Button(text='P L A Y', font_name='Roboto-Bold.ttf', size_hint=(.2, .15), on_release=self.callback,
pos_hint={'center_x': .5, "center_y": .3}, background_color = self.color, background_normal='')

Related

kivy transition between screens

i made a gui with python kivy with a starting screen that has a button in it which generates new screens when pressed, and it also generates new buttons so its easier to pick the screen i need to get in focus but i can't get it working properly cause i can't generate buttons on the newly made screens
when they aren't in focus, the script only generates buttons for the screen in focus it seems
from kivy.app import App
from kivy.uix.label import Label
from kivy.uix.button import Button
from kivy.uix.textinput import TextInput
from kivy.uix.floatlayout import FloatLayout
from kivy.uix.screenmanager import ScreenManager, Screen, FadeTransition
class ScreenManagement(ScreenManager):
def __init__(self, **kwargs):
super(ScreenManagement, self).__init__(**kwargs)
sm = ScreenManagement(transition=FadeTransition())
class newtab(Screen):
def __init__(self, **kwargs):
super(newtab, self).__init__(**kwargs)
self.bt1=(Button(text="New tab", size_hint =(.1, .1) ,pos_hint ={'center_x':.1, 'center_y':.94}))
self.add_widget(self.bt1)
self.bt1.bind(on_release=self.new_tab)
self.txt1 = TextInput(text='',size_hint =(.1, .1), pos_hint ={'center_x':.2, 'center_y':.75}, multiline=True)
self.add_widget(self.txt1)
def transition(self, instance):
self.manager.current = (instance.text)
for item in sm.screen_names:
self.bt2=(Button(text=item, size_hint =(.1, .1) ,pos_hint ={'center_x':(.1*sm.screen_names.index(item)+.1), 'center_y':.84}))
self.add_widget(self.bt2)
self.bt2.bind(on_release=self.transition)
def new_tab(self, *args):
n = len(self.manager.screen_names) ##number of screens+1
screen = newtab(name="screen {}".format(n)) #make new screen and give it number
self.manager.add_widget(screen)
self.manager.current = "screen 0"
for item in sm.screen_names:
self.bt2=(Button(text=item, size_hint =(.1, .1) ,pos_hint ={'center_x':(.1*sm.screen_names.index(item)+.1), 'center_y':.84}))
self.add_widget(self.bt2)
self.bt2.bind(on_release=self.transition)
sm.add_widget(newtab(name='screen 0'))
class Application(App):
def build(self):
return sm
if __name__ == "__main__":
Application().run()
I suppose that below is what you expected to get. But I agree with #ApuCoder that you may look for TabbedPanel functionality.
from kivy.app import App
from kivy.uix.label import Label
from kivy.uix.button import Button
from kivy.uix.textinput import TextInput
from kivy.uix.floatlayout import FloatLayout
from kivy.uix.screenmanager import ScreenManager, Screen, FadeTransition
class ScreenManagement(ScreenManager):
def __init__(self, **kwargs):
super(ScreenManagement, self).__init__(**kwargs)
sm = ScreenManagement(transition=FadeTransition())
class newtab(Screen):
def __init__(self, **kwargs):
super(newtab, self).__init__(**kwargs)
self.bt1 = (Button(text="New tab", size_hint=(.1, .1), pos_hint={'center_x': .1, 'center_y': .94}))
self.add_widget(self.bt1)
self.bt1.bind(on_release=self.new_tab)
self.txt1 = TextInput(text='', size_hint=(.1, .1), pos_hint={'center_x': .2, 'center_y': .75}, multiline=True)
self.add_widget(self.txt1)
# add all present screen buttons to newly created screen
for i, screen in enumerate(sm.screens):
self.bt2 = (Button(text=screen.name, size_hint=(.1, .1), pos_hint={'center_x': (.1 * i + .1), 'center_y': .84}))
self.add_widget(self.bt2)
self.bt2.bind(on_release=self.transition)
# add this newly created screen button to all screens
for screen in sm.screens + [self]:
screen.bt2 = (Button(text=self.name, size_hint=(.1, .1), pos_hint={'center_x': (.1 * len(sm.screens) + .1), 'center_y': .84}))
screen.add_widget(screen.bt2)
screen.bt2.bind(on_release=screen.transition)
def transition(self, instance):
self.manager.current = instance.text
def new_tab(self, *args):
n = len(self.manager.screen_names) ##number of screens+1
screen = newtab(name="screen {}".format(n)) # make new screen and give it number
self.manager.add_widget(screen)
self.manager.current = "screen 0"
sm.add_widget(newtab(name='screen 0'))
class Application(App):
def build(self):
return sm
if __name__ == "__main__":
Application().run()

Kivy: Create a list of coloured labels using build() method

I want to create a list of coloured labels. The thing is that I could do it with the kv file, but I need to do it through the build() method. So I tried replicate what I have done, but it does not work. And I can't understand why.
This is what I've coded
from kivy.app import App
from kivy.uix.relativelayout import RelativeLayout
from kivy.uix.button import Button
from kivy.uix.label import Label
from kivy.uix.boxlayout import BoxLayout
from kivy.graphics import *
class RL(RelativeLayout): # Creates the background colour for each label
def __init__(self, **kwargs):
super().__init__(**kwargs)
with self.canvas:
Color(.7, 0, .5, 1)
Rectangle(size_hint=self.size)
class MainMenu(BoxLayout):
N_LBLS = 8
labels_text = []
RL_list = []
def __init__(self, **kwargs):
super().__init__(**kwargs)
button = Button(text='do something')
button.bind(on_release=self.change_text)
box = BoxLayout(orientation='vertical', padding= 10, spacing = 15)
for i in range(0, self.N_LBLS):
self.RL_list.append(RL())
self.labels_text.append(Label(text=f'{i}º label', size_hint=self.size))
self.RL_list[i].add_widget(self.labels_text[i])
box.add_widget(self.RL_list[i])
self.add_widget(button)
self.add_widget(box)
def change_text(self, instance):
for lbl in self.labels_text:
if lbl.text[0] == '5':
lbl.text = 'Text changed'
class MainApp(App):
def build(self):
return MainMenu()
if __name__ == '__main__':
MainApp().run()
It's supposed to make a button to the left, and a list of 8 coloured labels to the right.
The problem is that you are setting size_hint=self.size in each Label. The self.size is the size of the MainMenu, which is [100,100] when that code is executed. Note that size_hint is a multiplier that is applied to the parents size to calculate the widgets size. So a size_hint of [100,100] makes each Label 100 times bigger than the MainMenu. So your code is working, but the Labels are so large that the text is off the screen. Start by just removing size_hint=self.size.
And, to set a background color on a Label, you can just use the canvas of that Label, rather than some container. Here is a version of your code that does that:
from kivy.app import App
from kivy.lang import Builder
from kivy.uix.button import Button
from kivy.uix.label import Label
from kivy.uix.boxlayout import BoxLayout
class ColorLabel(Label):
pass
Builder.load_string('''
<ColorLabel>:
bg_color: [.7, 0, .5, 1]
canvas.before:
Color:
rgba: self.bg_color
Rectangle:
pos: self.pos
size: self.size
''')
class MainMenu(BoxLayout):
N_LBLS = 8
labels_text = []
def __init__(self, **kwargs):
super().__init__(**kwargs)
button = Button(text='do something')
button.bind(on_release=self.change_text)
box = BoxLayout(orientation='vertical', padding=10, spacing=15)
for i in range(0, self.N_LBLS):
self.labels_text.append(ColorLabel(text=f'{i}º label'))
box.add_widget(self.labels_text[i])
self.add_widget(button)
self.add_widget(box)
def change_text(self, instance):
for lbl in self.labels_text:
if lbl.text[0] == '5':
lbl.text = 'Text changed'
lbl.bg_color = [0, 1, 0, 1]
class MainApp(App):
def build(self):
return MainMenu()
if __name__ == '__main__':
MainApp().run()

How to store to list in kivy?

I am making kivy app, something like project manager. I've got problem, i'll try to describe it.
In my app you can create new "project" by pressing button, then open the project and create some task. I need to store "project" into list or dictioniares. I've been thinking about this problem whole week and I can't solve. Do you have any ideas? I include my py. file and my kv. file here.
If you have some improvments to my codes, come here with them.
My python file:
from kivy.app import App
import sys
from kivy.storage.jsonstore import JsonStore
from kivy.uix.screenmanager import ScreenManager,Screen, SlideTransition, RiseInTransition
from kivy.uix.floatlayout import FloatLayout
from kivy.uix.togglebutton import ToggleButton
from kivy.uix.boxlayout import BoxLayout
from kivy.uix.checkbox import CheckBox
from kivy.uix.label import Label
from kivy.uix.textinput import TextInput
from kivy.uix.button import Button
from kivy.uix.behaviors import ButtonBehavior
from kivy.lang import Builder
from kivy.properties import ObjectProperty
from kivy.uix.widget import Widget
from kivy.core.window import Window
from kivy.uix.image import Image
from kivy.uix.checkbox import CheckBox
from kivy.core.window import Window
from kivy.graphics import Color, Ellipse, Rectangle, Line
from kivy.uix.spinner import Spinner
from kivy.uix.stencilview import StencilView
Window.size = (400, 650)
Window.clearcolor = (0,0,0,0)
kv = Builder.load_file('main.kv')
c = 0
class MS(Screen, Widget):
def on_exit(self):
sys.exit()
class SES(Screen):
pass
class OPS(Screen, BoxLayout):
themes = ["DARK","LIGHT"]
def __init__(self, **kwargs):
super(OPS, self).__init__(**kwargs)
label = Label(text="COLOR THEME:", size_hint=(.2,.1), pos_hint={"x":.25,"top":.9})
self.add_widget(label)
tgbt = ToggleButton(text="DARK", size_hint=(.2, .1), pos_hint={"x":.5,"top":.9},background_normal="",background_color =(0,0,0,0))
self.add_widget(tgbt)
tgbt2 = ToggleButton(text="LIGHT", size_hint=(.2, .1), pos_hint={"x": .7, "top": .9},background_normal="", background_color= (1,1,1,1))
self.add_widget(tgbt2)
class PRS(Screen, BoxLayout):
widgets1 = []
l1x = .1
l1top = .87
txt1x = .4
txt1top = .88
ck1x = .64
ck1top = .88
chtop = 0.88
deltop = 0.88
projects = []
def changer(self,*args):
self.manager.current = 'task'
def changer2(self, *args):
self.manager.current = 'main'
def new_pr(self, *args):
txt1 = TextInput(multiline=False,size_hint=(0.3,0.05), pos_hint={'x':self.txt1x,"top":self.txt1top})
self.add_widget(txt1)
label1 = Label(text="YOUR PROJECT NAME:",size_hint=(0.2,0.04),pos_hint={"x":self.l1x,"top":self.l1top})
self.add_widget(label1)
check1 = CheckBox(active=False, size_hint=(0.2,0.05), pos_hint={"x":self.ck1x,"top":self.ck1top})
self.add_widget(check1)
print(self.projects)
self.widgets1.append(check1)
self.widgets1.append(label1)
self.widgets1.append(txt1)
self.l1top = self.l1top - .07
self.txt1top = self.txt1top - .07
self.ck1top = self.ck1top - .07
spinner = Spinner(text="OPTIONS", values="DELETE",background_normal="",background_color =(200/255.0, 194/255.0, 136/255.0,1))
button = Button(text="OPEN",color=(200 / 255.0, 194 / 255.0, 136 / 255.0, 1), size_hint=(0.1,0.05), pos_hint={"x":0.77, "top":self.chtop})
self.add_widget(button)
self.widgets1.append(button)
button2 = Button(text = "DELETE",color=(200 / 255.0, 194 / 255.0, 136 / 255.0, 1), size_hint=(0.13,0.05), pos_hint={"x":0.87,"top":self.deltop})
self.add_widget(button2)
self.widgets1.append(button2)
self.chtop = self.chtop - 0.07
self.deltop = self.deltop - 0.07
button.bind(on_press= self.changer)
button2.bind(on_release= self.remover)
def remover(self, *args):
for i in self.widgets1:
self.remove_widget(i)
self.l1top = .88
self.deltop = .88
self.chtop = .88
self.ck1top = .88
self.txt1top = .88
def __init__(self, **kwargs):
super(PRS, self).__init__(**kwargs)
bt1 = (Button(text="NEW PROJECT",pos_hint={"x":.0,"top":1},size_hint=(.5,.1)))
self.add_widget(bt1)
bt2 = (Button(text="BACK",pos_hint={"x":.5,"top":1},size_hint=(.5,.1)))
self.add_widget(bt2)
bt1.bind(on_release=self.new_pr)
bt2.bind(on_release=self.changer2)
def clear_screen(self):
self.canvas.clear()
class TASKS(Screen, BoxLayout):
task1 = []
tinpx = 0.25
tinptop = .83
chkx = 0.76
chktop = .84
showed = False
def note(self, *args):
self.showed = True
if self.showed == True:
textinput = TextInput(multiline=True,size_hint=(.4,.5), pos_hint={"x":0.56,"top":self.chktop-0.1})
self.add_widget(textinput)
while self.showed == False:
self.remove_widget(textinput)
break
def change(self, *args):
self.showed = False
def changer(self,*args):
self.manager.current = 'project'
def new_task(self, *args):
txt1 = TextInput(multiline=False, size_hint=(.2,.04), pos_hint={"x":self.tinpx, "top":self.tinptop})
self.add_widget(txt1)
chck1 = CheckBox(active=False, size_hint = (.2, .05), pos_hint = {"x":self.chkx,"top":self.chktop})
self.add_widget(chck1)
notes = Button(text="NOTES", color=(200 / 255.0, 194 / 255.0, 136 / 255.0, 1), size_hint=(.2,.05), pos_hint={"x":0.56,"top":self.chktop})
notes.bind(on_press=self.note)
notes.bind(on_release=self.change)
self.add_widget(notes)
self.tinptop = self.tinptop - .07
self.chktop = self.chktop - .07
def __init__(self, **kwargs):
super(TASKS, self).__init__(**kwargs)
self.add_widget(Label(text="TASK NAME", size_hint=(.2,.04), pos_hint={"x":0.25,"top":.88}))
self.add_widget(Label(text="COMPLETE", size_hint = (.2,.04), pos_hint={"x":0.75,"top":.88}))
bt1 = Button(text="NEW TASK",color=(0,0,0),size_hint=(.5,.1), pos_hint = {"x":0, "top":1},background_normal="",background_color =(200/255.0, 194/255.0, 136/255.0,1))
self.add_widget(bt1)
homebt = Button(text="BACK",color=(0,0,0),size_hint=(.5, .1), pos_hint={"x":0.5,"top":1},background_normal="",background_color =(200/255.0, 194/255.0, 136/255.0,1))
self.add_widget(homebt)
homebt.bind(on_release=self.changer)
bt1.bind(on_release=self.new_task)
class Help(Screen, Widget):
pass
class MApp(App):
title = "PROJECT MANAGER"
def build(self):
wid = PRS(size_hint=(None, None), size=Window.size)
sm = ScreenManager()
sm.add_widget(MS(name = "main"))
sm.add_widget(SES(name = "second"))
sm.add_widget(OPS(name = "options"))
sm.add_widget(PRS(name="project"))
sm.add_widget(TASKS(name="task"))
sm.add_widget(Help(name="help"))
return sm
if __name__ == "__main__":
MApp().run()
My kv. file:
<MS>:
GridLayout:
cols:7
GridLayout:
cols:2
Button:
text : "NEW"
color:0,0,0
on_release:app.root.current="project"
background_normal:""
background_color:(200/255.0, 194/255.0, 136/255.0,1)
Button:
text : "OPTIONS"
color:0,0,0
on_release:app.root.current="options"
background_normal:""
background_color:(200/255.0, 194/255.0, 136/255.0,1)
Button:
text : "LOAD"
color:0,0,0
on_release:app.root.current="second"
background_normal:""
background_color:(200/255.0, 194/255.0, 136/255.0,1)
Button:
text : "HELP"
color:0,0,0
on_release:app.root.current="help"
background_normal:""
background_color:(200/255.0, 194/255.0, 136/255.0,1)
Button:
text : "Next"
color:0,0,0
on_release:app.root.current="second"
background_normal:""
background_color:(200/255.0, 194/255.0, 136/255.0,1)
Button:
id:bt1
text : "Exit"
color:0,0,0
background_normal:""
background_color:(200/255.0, 194/255.0, 136/255.0,1)
on_release:app.stop()
<SES>:
name:"second"
Button:
text:"back"
color:0,0,0
on_release:
app.root.current="main"
<OPS>:
name:"options"
BoxLayout:
Button:
size_hint:.5,.2
pos_hint : {"x":.5,"top":.15}
text: "HOME"
color:0,0,0
on_release:app.root.current="main"
<PRS>:
name:"project"
<TASKS>:
name:"task"
<Help>:
name:"help"
GridLayout:
Label:
text:"COMING SOON!!!"
color:0,0,0
Thaks for help, time and effort.
Micheno
Here is simple example of my problem.
from kivy.app import App
from kivy.uix.label import Label
from kivy.uix.button import Button
from kivy.uix.boxlayout import BoxLayout
class Test(BoxLayout):
x1 = 0.2
top1 = 0.9
widgets = []
def adder(self, *args):
lb1 = Label(text="HELLO WORLD", pos_hint={"x":self.x1,"top":self.top1})
self.add_widget(lb1)
self.x1 = self.x1 - 0.05
self.top1 = self.top1 - 0.05
self.widgets.append(lb1)
def remover(self, *args):
for i in self.widgets:
self.remove_widget(i)
self.x1=0.2
self.top1 = 0.9
def __init__(self, **kwargs):
super(Test, self).__init__(**kwargs)
bt1 = Button(text="ADD", pos_hint={"x":.1,"top":1}, size_hint=(0.2,0.4))
self.add_widget(bt1)
removebt = Button(text = "REMOVE",pos_hint={"x":.4,"top":1}, size_hint=(0.2,0.4))
self.add_widget(removebt)
removebt.bind(on_release=self.remover)
bt1.bind(on_release=self.adder)
class APP(App):
def build(self):
return Test()
if __name__ == "__main__":
APP().run()
If i want to delete only one label it will delete all. Just try to copy and run it
Just remove the last Label in the list:
def remover(self, *args):
if len(self.widgets) > 0:
self.remove_widget(self.widgets.pop(-1))
OK i could delete last that's improvement, but my problem is like this. What if I with button "ADD" I add text and button to remove the text and the button itself. Here is my new example with yours improvment.
from kivy.app import App
from kivy.uix.label import Label
from kivy.uix.button import Button
from kivy.uix.boxlayout import BoxLayout
from kivy.core.window import Window
Window.size = (400, 650)
class Test(BoxLayout):
x1 = 0.1
top1 = 0.9
widgets = []
def adder(self, *args):
lb1 = Label(text="HELLO WORLD", pos_hint={"x":self.x1,"top":self.top1})
self.add_widget(lb1)
removebt = Button(text = "REMOVE",pos_hint={"x":self.x1-0.1,"top":self.top1}, size_hint=(0.5,0.1))
self.add_widget(removebt)
self.widgets.append(removebt)
removebt.bind(on_release=self.remover)
self.widgets.append(lb1)
self.top1 = self.top1 - 0.05
def remover(self, *args):
if len(self.widgets) > 0:
self.remove_widget(self.widgets.pop(-1))
self.x1=0.2
self.top1 = 0.9
def __init__(self, **kwargs):
super(Test, self).__init__(**kwargs)
bt1 = Button(text="ADD", pos_hint={"x":.1,"top":1}, size_hint=(1,0.4))
self.add_widget(bt1)
bt1.bind(on_release=self.adder)
class APP(App):
def build(self):
return Test()
if __name__ == "__main__":
APP().run()

How to access a widget from one screen inside another screen in kivy

How do I access a widget from screen1 and make changes to it in screen2 and also return screen1 back to it initial state(like I just run the code).
I have commented out some code that is not working.
from kivy.app import App
from kivy.uix.label import Label
from kivy.uix.button import Button
from kivy.uix.screenmanager import ScreenManager, Screen, FadeTransition
class ScreenManagement(ScreenManager):
def __init__(self, **kwargs):
super(ScreenManagement, self).__init__(**kwargs)
class Screen2(Screen):
def __init__(self, **kwargs):
super(Screen2, self).__init__(**kwargs)
self.retry = Button(text='retry', font_size=15, size_hint=(.26, .26),
pos_hint={'center_x': .5, 'center_y': .32}, on_press=self.retrying,
background_color=(0, 0, 1, 1))
self.add_widget(self.retry)
def retrying(self, *args):
self.manager.current = 'screen1'
# it should change the text in screen1 to "i am back to screen1, thanks you"
#self.welc.text=" i am back to screen1, thank you"
# it should change the button color back to it normal state
#self.goto.background_color='normal state'
class Screen1(Screen):
def __init__(self, **kwargs):
super(Screen1, self).__init__(**kwargs)
self.welc = Label(text='hi there welcome to my first screen', font_size=15, size_hint=(.26, .26),
pos_hint={'center_x': .5, 'center_y': .7})
self.add_widget(self.welc)
self.goto = Button(text='next screen', font_size=15, size_hint=(.2, .2),
pos_hint={'center_x': .5, 'center_y': .32}, on_press=self.going, background_color=(0, 0, 1, 1))
self.add_widget(self.goto)
def going(self, *args):
self.goto.background_color=(1,0,0,1)
self.manager.current = 'screen2'
class Application(App):
def build(self):
sm = ScreenManagement(transition=FadeTransition())
sm.add_widget(Screen1(name='screen1'))
sm.add_widget(Screen2(name='screen2'))
return sm
if __name__ == "__main__":
Application().run()
My question is this:
how do i change the text in screen1 when the retry button is pressed.
How do i return screen1 back to it initial state after the retry button is pressed so that the "next screen" button color changes back to blue
Once you have changed the current screen to screen1, then you can access that Screen as self.manager.current_screen, so your retrying() method can be:
def retrying(self, *args):
self.manager.current = 'screen1'
self.manager.current_screen.welc.text = "i am back to screen1, thanks you"
self.manager.current_screen.goto.background_color = background_color=(0, 0, 1, 1)
To set the screen1 back to its original state, you could write another method that just sets all the values back to the original value one by one. Or you could recreate screen1 by doing something like this in a method of your Application.:
def reset_screen1(self):
sm = self.root
scr1 = sm.get_screen('screen1`)
sm.remove_widget(scr1)
sm.add_widget(Screen1(name='screen1'))

How to get value outside function using python and kivy

this is a simple python kivy app, only text label and slider. This code works fine.
from kivy.uix.screenmanager import ScreenManager, Screen
from kivy.uix.floatlayout import FloatLayout
from kivymd.app import MDApp
from kivymd.theming import ThemeManager
from kivymd.uix.slider import Slider
from kivy.properties import NumericProperty
from kivymd.uix.label import MDLabel
class Screen1(Screen):
def __init__(self, **kwargs):
super(Screen1, self).__init__(**kwargs)
layout = FloatLayout()
self.hours_value = MDLabel(text = "0", halign = "center", pos_hint = {'center_x':.5, 'center_y':.80}, theme_text_color = 'Error')
self.hours_slider = Slider(min = 0, max = 24, pos_hint = {'center_x':.5}, size_hint_x = .7)
self.hours_slider.bind(value = self.on_value_hours)
layout.add_widget(self.hours_value)
layout.add_widget(self.hours_slider)
self.add_widget(layout)
def on_value_hours(self, instance, slider):
self.hours_value.text = "%d"%slider
print(instance)
print("%d"%slider)
return slider
class myapp(MDApp):
def build(self):
self.theme_cls = ThemeManager()
self.theme_cls.primary_palette = 'Orange'
self.theme_cls.accent_pallete = 'Blue'
self.theme_cls.theme_style = 'Dark'
sm = ScreenManager()
sm.add_widget(Screen1(name = 's1'))
return sm
if __name__ == "__main__":
myapp().run()
But now I want to get value on slider outside my function def on_value_hours(self, instance, slider):
so I add this code my_value_slider = on_value_hours()
but I get a error on_value_hours() missing 3 required positional arguments: 'self', 'instance', and 'slider'
I tried to add my_value_slider = on_value_hours(1,1,1)
but this is also not working for me :(
give me a error AttributeError: 'int' object has no attribute 'hours_value'
this is a full code but still give me a error. I want to get value outside on my function. Please help me.
from kivy.uix.screenmanager import ScreenManager, Screen
from kivy.uix.floatlayout import FloatLayout
from kivymd.app import MDApp
from kivymd.theming import ThemeManager
from kivymd.uix.slider import Slider
from kivy.properties import NumericProperty
from kivymd.uix.label import MDLabel
class Screen1(Screen):
def __init__(self, **kwargs):
super(Screen1, self).__init__(**kwargs)
layout = FloatLayout()
self.hours_value = MDLabel(text = "0", halign = "center", pos_hint = {'center_x':.5, 'center_y':.80}, theme_text_color = 'Error')
self.hours_slider = Slider(min = 0, max = 24, pos_hint = {'center_x':.5}, size_hint_x = .7)
self.hours_slider.bind(value = self.on_value_hours)
layout.add_widget(self.hours_value)
layout.add_widget(self.hours_slider)
self.add_widget(layout)
def on_value_hours(self, instance, slider):
self.hours_value.text = "%d"%slider
print(instance)
print("%d"%slider)
return slider
my_value_slider = on_value_hours(1,1,1)
class myapp(MDApp):
def build(self):
self.theme_cls = ThemeManager()
self.theme_cls.primary_palette = 'Orange'
self.theme_cls.accent_pallete = 'Blue'
self.theme_cls.theme_style = 'Dark'
sm = ScreenManager()
sm.add_widget(Screen1(name = 's1'))
return sm
if __name__ == "__main__":
myapp().run()
You can do something like this:
class Screen1(Screen):
# slider value
my_value_slider = NumericProperty(0)
def __init__(self, **kwargs):
super(Screen1, self).__init__(**kwargs)
layout = FloatLayout()
self.hours_value = MDLabel(text = "0", halign = "center", pos_hint = {'center_x':.5, 'center_y':.80}, theme_text_color = 'Error')
self.hours_slider = Slider(min = 0, max = 24, pos_hint = {'center_x':.5}, size_hint_x = .7)
self.hours_slider.bind(value = self.on_value_hours)
layout.add_widget(self.hours_value)
layout.add_widget(self.hours_slider)
self.add_widget(layout)
def on_value_hours(self, instance, slider):
self.hours_value.text = "%d"%slider
print(instance)
print("%d"%slider)
# save value
self.my_value_slider = slider
return slider
Another approach is more like your initial code, where my_slider_value would be a class variable (as opposed to an instance variable):
class Screen1(Screen):
# class variable
my_value_slider = 0
def __init__(self, **kwargs):
super(Screen1, self).__init__(**kwargs)
layout = FloatLayout()
self.hours_value = MDLabel(text = "0", halign = "center", pos_hint = {'center_x':.5, 'center_y':.80}, theme_text_color = 'Error')
self.hours_slider = Slider(min = 0, max = 24, pos_hint = {'center_x':.5}, size_hint_x = .7)
self.hours_slider.bind(value = self.on_value_hours)
layout.add_widget(self.hours_value)
layout.add_widget(self.hours_slider)
self.add_widget(layout)
def on_value_hours(self, instance, slider):
self.hours_value.text = "%d"%slider
print(instance)
print("%d"%slider)
# update value of class variable
Screen1.my_value_slider = slider
return slider
You can then access my_value_slider as Screen1.my_value_slider. Note that no parens are used in that access. The disadvantage of this approach is that my_value_slider is not a Property, so you can't bind to it.

Categories