this is a trial code that I want to implement in my final project.
Python Code:
import kivy
kivy.require('1.0.6')
from kivy.app import App
from kivy.uix.boxlayout import BoxLayout
from kivy.uix.screenmanager import ScreenManager, Screen
from kivy.lang import Builder
class Wid(BoxLayout):
def settxt(self,i):
lab = self.ids['lab']
but = self.ids['but']
lab.text = "Label Number {}".format(i)
but.text = "Button Number {}".format(i)
class Win1(Screen):
i=0
def addw(self):
box1 = self.ids['box1']
self.i = self.i +1
w = Wid()
w.settxt(self.i)
box1.add_widget(w)
def switch(self):
sm.current="win2"
class Win2(Screen):
def switch(self):
sm.current="win1"
class WindowManager(ScreenManager):
pass
kv = Builder.load_file("test.kv")
sm = WindowManager()
screens = [Win1(name="win1"), Win2(name="win2")]
for screen in screens:
sm.add_widget(screen)
sm.current = "win1"
class Test(App):
def build(self):
return sm
if __name__ == '__main__':
Test().run()
Kivy Code:
<Wid>:
lab:lab
but:but
BoxLayout:
height: self.minimum_height
size: root.size
Label:
id: lab
Button:
id: but
<Win1>
name:"win1"
box1:box1
BoxLayout:
height: self.minimum_height
orientation: "vertical"
BoxLayout:
size_hint: 1,0.2
Button:
text:"window 2"
on_release:
root.switch()
Button:
text:"add wid"
on_release:
root.addw()
ScrollView:
GridLayout:
id:box1
orientation: "vertical"
spacing: 2
size_hint_y: None
height: self.minimum_height
row_default_height: 60
cols:1
<Win2>
name: "win2"
BoxLayout:
id: bl
height: bl.minimum_height
size_hint_y: None
Button:
text:"window 2"
on_release:
root.switch()
With the press of the switch, I expect that my custom widget to get in the gridlayout in the scrollview, one below the other. But instead, each new widget appears in the last cell of the layout and overlaps on the previous one and empty cells keep on forming above them.
Don't know where it's going wrong.
Here I have moved the kv to a separate file, and dynamically created the screens.
Key points: I add the screens dynamically in on_start, this is after the build has completed. I create the ScreenManager in kv, and use the id to add the screens. In the kv code I put the ScreenManger in a BoxLayout. This is a personal preference. I do this so when accessing objects the root widget is not the screen manager. Therefore in the switch() methods, the addressing uses the assigned id, rather than relying on the root widget being a screenmanager.
FWIW: If the switch code is only going to change screens I would move those single lines into KV.
import kivy
kivy.require('1.0.6')
from kivy.app import App
from kivy.lang import Builder
from kivy.uix.boxlayout import BoxLayout
from kivy.uix.screenmanager import Screen
class Wid(BoxLayout): # Change to layout
def settxt(self, i):
lab = self.ids['lab']
but = self.ids['but']
lab.text = "Label Number {}".format(i)
but.text = "Button Number {}".format(i)
class Win1(Screen):
i = 0
def addw(self):
box1 = self.ids['box1']
self.i = self.i + 1
w = Wid()
w.settxt(self.i)
box1.add_widget(w)
#staticmethod
def switch():
app = App.get_running_app()
app.root.ids.sm.current = "win2"
class Win2(Screen):
#staticmethod
def switch():
app = App.get_running_app()
app.root.ids.sm.current = "win1"
class WidgetQ1App(App):
def build(self):
return Builder.load_file('widgetq.kv')
def on_start(self):
screens = [Win1(name="win1"), Win2(name="win2")]
sm = self.root.ids.sm
for screen in screens:
sm.add_widget(screen)
WidgetQ1App().run()
And the KV code:
<Wid>: # Put widgets in a layout, not a widget.
lab:lab
but:but
BoxLayout:
size: root.size
Label:
id: lab
Button:
id: but
<Win1>
# name:"win1"
box1:box1
BoxLayout:
orientation: "vertical"
BoxLayout:
size_hint: 1,0.2
Button:
text:"window 2"
on_release:
root.switch()
Button:
text:"add wid"
on_release:
root.addw()
ScrollView:
GridLayout:
id:box1
orientation: "vertical"
spacing: 2
size_hint_y: None
height: self.minimum_height
row_default_height: 60
cols:1
<Win2>:
# name: "win2"
BoxLayout:
Button:
text:"window 2"
on_release:
root.switch()
BoxLayout:
ScreenManager:
id: sm
<win2>
name: "win2"
size_hint_y: None
height: bl.minimum_height
BoxLayout:
id: bl
Button:
text:"window 2"
on_release:
root.switch()
Your custom widgets don't have a height defined, try changing to something like the above.
Also, start your class names with an upper case letter, kv requires this in some cases. For instance, win2 should be Win2.
A number of issues here, see the comments. The biggest problem I see is putting items in a widget. Put Widgets in a layout, not other widgets.
import kivy
kivy.require('1.0.6')
from kivy.app import App
from kivy.uix.boxlayout import BoxLayout
from kivy.uix.screenmanager import Screen
from kivy.lang import Builder
kv = """
<Wid>: # Put widgets in a layout, not a widget.
lab:lab
but:but
BoxLayout:
size: root.size
Label:
id: lab
Button:
id: but
<Win1>
# name:"win1"
box1:box1
BoxLayout:
orientation: "vertical"
BoxLayout:
size_hint: 1,0.2
Button:
text:"window 2"
on_release:
root.switch()
Button:
text:"add wid"
on_release:
root.addw()
ScrollView:
GridLayout:
id:box1
orientation: "vertical"
spacing: 2
size_hint_y: None
height: self.minimum_height
row_default_height: 60
cols:1
<Win2>:
# name: "win2"
BoxLayout:
Button:
text:"window 2"
on_release:
root.switch()
ScreenManager:
id: sm
Win1:
name: 'win1'
Win2:
name: 'win2'
"""
class Wid(BoxLayout): # Change to layout
def settxt(self,i):
lab = self.ids['lab']
but = self.ids['but']
lab.text = "Label Number {}".format(i)
but.text = "Button Number {}".format(i)
class Win1(Screen):
i = 0
def addw(self):
box1 = self.ids['box1']
self.i = self.i + 1
w = Wid()
w.settxt(self.i)
box1.add_widget(w)
#staticmethod
def switch():
app = App.get_running_app()
app.root.current = "win2"
class Win2(Screen):
#staticmethod
def switch():
app = App.get_running_app()
app.root.current = "win1"
# class WindowManager(ScreenManager):
# pass
# kv = Builder.load_file("test.kv")
# sm = WindowManager()
#
# screens = [win1(name="win1"), win2(name="win2")]
# for screen in screens:
# sm.add_widget(screen)
#
# sm.current = "win1"
class WidgetQApp(App):
def build(self):
return Builder.load_string(kv)
WidgetQApp().run()
Related
I want to remove a Boxlayout in my widget, but I cant.
There is a Boxlayout at the begining of the app called "Speca". After my sellections it must be removed.
When you run the app, sellect something in "Home" Spinner and click any of the new Toggle buttons.
Wtih the press of any of the Toggle buttons "Speca" must disappear.
Please help.
Here is main.py:
from kivy.app import App
from kivy.uix.gridlayout import GridLayout
from kivy.uix.widget import Widget
from kivy.uix.boxlayout import BoxLayout
from kivy.uix.scrollview import ScrollView
from kivy.uix.spinner import Spinner
from kivy.uix.button import Button
from kivy.uix.label import Label
from kivy.properties import ObjectProperty, StringProperty, BooleanProperty
from kivy.properties import ListProperty
from collections import OrderedDict
from kivy.uix.togglebutton import ToggleButton
data1=["mother","father","son"]
data2=["uncle","aunt","grandfather"]
data3=["jack","mike","simon"]
data4=["1898","1975","1985","1885"]
amd="0dp"
class MainWidget(Widget):
def remove_layout(self, *ignore):
self.remove_widget(self.layout)
global amd
an0=tuple(list(OrderedDict.fromkeys(data1)))
cal5= ObjectProperty()
cal6= ObjectProperty()
def btn10(self,text):
if self.cal5:
self.cal5.parent.remove_widget(self.cal5)
self.cal5 =ModelSpecifications()
a=data2
b=data3
c=data4
mi=[]
n=0
while n < len(a):
aba=n
mi.append(aba)
n+=1
for i in mi:
self.b1=MyTButton(text=str(i),size_hint=(1,None),height="100dp",group="selections")
self.cal5.add_widget(self.b1)
self.ids.scd.add_widget(self.cal5, index=3)
def on_state(self, togglebutton): #<----THIS IS THE TUGGLEBUTTON I WANT USE
global amd
tb = togglebutton
text1=tb.text
if text1=="0":
amd="50dp"
elif text1=="1":
amd="100dp"
else:
amd="200dp"
if self.cal6:
self.cal6.parent.remove_widget(self.cal6)
self.cal6 =Spec()
self.ids.scd.add_widget(self.cal6, index=2)
class SecondPage(ScrollView):
pass
class Speca(BoxLayout): #<------ THIS IS THE BOXLAYOUT I WANT TO REMOVE
pass
class Spec(BoxLayout):
def __init__(self, **kwargs):
super().__init__(**kwargs)
self.size_hint=(1,None)
self.height=amd
class MyTButton(ToggleButton):
def __init__(self, **kwargs):
super().__init__(**kwargs)
class ModelSpecifications(BoxLayout): #this is the class I want add after my spinner selection
pass
class Calculation(GridLayout):
pass
class MyApp(App):
pass
MyApp().run()
here is my.kv :
MainWidget:
<MainWidget>:
hideable: hideable
ScreenManager:
id: scmanager
size: root.width, root.height
Screen:
id: scndpage
name: "second"
SecondPage:
Calculation:
id:scd
cols:1
height: self.minimum_height
row_default_height: "70dp"
size_hint_y: None
spacing:"10dp"
canvas.before:
Rectangle:
pos: self.pos
size: self.size
BoxLayout:
size_hint: 1, None
height: "50dp"
pading:"10dp"
spacing:"10dp"
orientation: "vertical"
BoxLayout:
orientation: "horizontal"
Label:
text:"Name:"
color: 0,0,0,1
TextInput:
text:"---"
color: 0,0,0,1
Label:
text:"Surname:"
color: 0,0,0,1
TextInput:
text:"-----"
color: 0,0,0,1
BoxLayout:
id:scdd
size_hint: 1, 1
height: "100dp"
orientation: "vertical"
BoxLayout:
size_hint: 1, None
height: "50dp"
orientation: "horizontal"
Label:
text: " Sellection:"
color: 0,0,0,1
Spinner:
text: 'Home'
values: root.an0
on_text: app.root.btn10(self.text)
Speca: #<------ THIS IS THE BOXLAYOUT I WANT TO REMOVE
Button:
text:" Calculate"
Button:
text:"Sellect"
Button:
text:"Back"
<ModelSpecifications>:
id:anss
pading:"10dp"
spacing:"10dp"
size_hint: 1, None
height: "100dp"
orientation: "horizontal"
<MyTButton#ToggleButton>: #<----THIS IS THE TUGGLEBUTTON I WANT USE
on_state:
app.root.on_state(self)
<Speca>: #<------ THIS IS THE BOXLAYOUT I WANT TO REMOVE
orientation:"vertical"
Label:
color: (1,1,0,1)
text:"I WANT TO REMOVE THIS PART WHEN I PRESS ANY OF TOGGLE BUTTONS"
Please run the app and see it.
Looks to me like speca is a child of the calculation widget with ID scd. So give speca an ID and then Remove speca via ids in on_srate python function.
Kv
SecondPage:
Calculation:
id:scd
speca:
id: speca
py
def on_state():
self.root.ids.scd.remove_widget(self.root.ids.speca)
YES.
When I make those changes;
Kv
SecondPage:
Calculation:
id:scd
speca:
id: speca
py
def on_state():
self.ids.scd.remove_widget(self.ids.speca)
It works.
I am a new programmer, working on a Kivy app and I need to use screens (screen manager), the issue is that I am using element cards as but buttons, and it is supposed that when using on_release it will change the screen, however if I include root.manager.transition.direction = "left" I get the error AttributeError: 'MyContentComunes' object has no attribute 'screen'. I don't know if anyone could help me with this.
Here is a piece of code.
from kivy.app import App
from kivymd.app import MDApp
from kivy.lang import Builder
from kivy.uix.boxlayout import BoxLayout
from kivymd.uix.expansionpanel import MDExpansionPanel, MDExpansionPanelTwoLine
from kivy.core.window import Window
from kivymd.color_definitions import colors
from kivy.uix.screenmanager import ScreenManager, Screen
from kivymd.uix.screen import MDScreen
KV = '''
WindowManager:
id: screen_manager
PrincipalWindow:
LenghtWindow:
<PrincipalWindow>:
name: "principal"
BoxLayout:
MDToolbar:
title: "Conversor"
pos_hint: {"top": 1}
ScrollView:
pos_hint: {"center_x": .5, "center_y": .5} #Ubicación
size_hint: 0.90, 0.75
GridLayout:
halign: 'center'
cols: 1
adaptive_height: True
id: box
<LenghtWindow>:
name: "Lenght"
md_bg_color: 0.34,0.024,0.292,1
MDBoxLayout:
orientation: "vertical"
MDToolbar:
title: "Conversor"
pos_hint: {"top": 1}
Button:
text: "Back"
font_size: 32
on_release:
app.root.current = "principal"
root.manager.transition.direction = "right"
<MyContentComunes>:
orientation: 'vertical'
padding: dp(10)
spacing: dp(10)
size_hint_y: None
height: self.minimum_height
ElementCard:
image:"1490820814-13_82405.png"
text:"Longitud"
id:longitud
on_release:
app.root.current = "Lenght"
root.manager.transition.direction = "left"
<ElementCard#MDCard>:
md_bg_color: app.theme_cls.primary_color
padding: dp(15)
spacing: dp(15)
size_hint: 1, None
ripple_behavior: True
# on_release: print("worked")
image:''
text:""
items_count:""
subtext:''
orientation: "vertical"
Image:
source:root.image
halign:"center"
padding: dp (4)
spacing: dp(4)
MDBoxLayout:
orientation: "vertical"
MDLabel:
halign:"center"
text:root.text
MDLabel:
halign:"center"
font_style:"Caption"
text:root.subtext
'''
Window.size = 324, 720
class Conversor(MDApp):
def build(self):
self.theme_cls.primary_palette = "Blue"
return Builder.load_string(KV)
def __init__(self, **kwargs):
super().__init__(**kwargs)
self.list_items = [] # Dictionary where the items are stored
self.category_list1 = ['Comunes']
def on_start(self):
for category in self.category_list1:
self.root.get_screen('principal').ids.box.add_widget(
MDExpansionPanel(
icon="3.png",
content=MyContentComunes(),
panel_cls=MDExpansionPanelTwoLine(
text=category,
secondary_text="Ver las unidades"
)
)
)
class MyContentComunes(BoxLayout):
pass
class PrincipalWindow(Screen):
pass
class LenghtWindow(Screen):
pass
class WindowManager(ScreenManager):
pass
Conversor().run()
The element card is inside an expansion panel, which is also inside a screen.
Try adding Screen to class MyContentComunes.
class MyContentComunes(BoxLayout, Screen):
pass
And I recommend you to organize your code like this. It will make your work more eaisier.
from kivy.app import App
from kivymd.app import MDApp
# import libraries ...
KV = '''
# Your KV File
'''
Window.size = 324, 720
class MyContentComunes(BoxLayout, Screen):
pass
class PrincipalWindow(Screen):
pass
class LenghtWindow(Screen):
pass
class WindowManager(ScreenManager):
pass
class Conversor(MDApp):
def build(self):
self.theme_cls.primary_palette = "Blue"
return Builder.load_string(KV)
def __init__(self, **kwargs):
# Code
.
.
.
def on_start(self):
# Code
.
.
.
Conversor().run()
I was using my main class as widget and was passing IDs from kv file to python without problems.
Now changed it to a screen as I need to switch between 2 screens but now I cant access the IDs declared in kv file. I get error - 'MainScreen'object has no attribute 'labINFO' - (this is the first label id I am trying to modify.)
Here are parts of py and kv files
from kivy.app import App
from kivy.uix.floatlayout import FloatLayout
from kivy.uix.gridlayout import GridLayout
from kivy.uix.label import Label
from kivy.uix.button import Button
from kivy.uix.textinput import TextInput
from kivy.uix.widget import Widget
from kivy.properties import ObjectProperty
from kivy.core.window import Window
from kivy.uix.popup import Popup
from kivy.uix.screenmanager import ScreenManager, Screen
from kivy.clock import Clock
class GSMNosScreen(Screen):
def gsmclose(self, obj):
Clock.schedule(self.startgetTemps,dataInterval)
BoilerApp.sm.current = 'main'
class MainScreen(Screen):
....
....
def __init__(self, **kwargs):
super(MainScreen, self).__init__(**kwargs)
self.labINFO.text = "Waiting for Pic..."
self.labM1.text = str(b1Min)
self.labM2.text = str(b2Min)
sm = ScreenManager() #transition=NoTransition()
sm.add_widget(MainScreen(name='main'))
sm.add_widget(GSMNosScreen(name='gsmnos'))
class BoilerApp(App):
def build(self):
self.title = 'Boiler Monitor'
return sm
if __name__ == "__main__":
from kivy.core.window import Window
Window.fullscreen = True
app = BoilerApp()
app.run()
KV file
<GSMNosScreen>:
labN1: labN1
size_hint: .5, .5
auto_dismiss: False
title: "GSM Numbers" # <<<<<<<<
separator_height: 0 # <<<<<<<<
GridLayout:
cols: 1
size: root.width, root.height
MyTLab:
id:labN1
font_size: 20
text: "Number 1 : ..."
MyBut:
text: "Close"
font_size: 20
size_hint: .2, .2
on_press: gsmclose()
<MainScreen>
labM1: labM1
labM2: labM2
labM3: labM3
labM4: labM4
labM5: labM5
labINFO: labINFO
labDT: labDT
GridLayout:
cols: 1
size: root.width, root.height
MyTLab:
text: "Monitor"
underline: True
size_hint: .5, .2
BoxLayout:
orientation: "horizontal"
size_hint_y: .2
MySTLab:
color: 0.8,.2,.2,0.7
text: "Min °C"
size_hint_x: 1.5
font_size: 25
MyMLab:
id: labM1
text: "50"
MyMLab:
id: labM2
text: "50"
MyMLab:
id: labM3
text: "50"
MyMLab:
id: labM4
text: "50"
BoxLayout:
orientation: "horizontal"
#cols:2
size_hint_y: .1
Label:
id: labDT
color: 0,1,0.5,0.8
text: "Starting ...."
font_size: sp(20)
size_hint_x: .3
Label:
id: labINFO
color: 0,1,0.5,0.8
text: "...."
font_size: sp(20)
size_hint_x: .7
I believe the problem is that the kv file has not been loaded yet when the lines:
sm = ScreenManager() #transition=NoTransition()
sm.add_widget(MainScreen(name='main'))
sm.add_widget(GSMNosScreen(name='gsmnos'))
are executed.
Try moving the above lines into the build() method of the App:
class BoilerApp(App):
def build(self):
self.title = 'Boiler Monitor'
sm = ScreenManager() # transition=NoTransition()
sm.add_widget(MainScreen(name='main'))
sm.add_widget(GSMNosScreen(name='gsmnos'))
return sm
The kv file (if it is named boiler.kv) is loaded before the build() mehod is called.
I've been at this for hours now, trying every solution I could find on here and trying random things....
I'm trying to build a layout consisting of 3 buttons at the top, then a scroll-able GridLayout or BoxLayout. I just cant figure out whats wrong... I've read on one response "bind the layout's size to adapt itself:" but I'm using screenmanagement and cant figure out how to do that with my code setup
<HomeScreen>:
BoxLayout:
orientation: "vertical"
BoxLayout:
size_hint: 1,.1
orientation: "horizontal"
Button:
text:"1"
Button:
text:"2"
Button:
text:"3"
ScrollView:
GridLayout:
orientation: "vertical"
size_hint_y: None
row_default_height: 60
cols:1
Button:
Button:
Button:
Button:
Button:
Button:
Button:
Button:
Button:
Button:
Button:
Button:
Button:
Button:
Button:
Button:
Your code is correct, you just need to specify the height of the GridLayout. You can use height: self.minimum_height.
Reproducible example:
from kivy.app import App
from kivy.uix.screenmanager import ScreenManager, Screen
from kivy.lang import Builder
kv_text = '''
<MyScreenManager>:
HomeScreen:
<HomeScreen>:
BoxLayout:
orientation: "vertical"
BoxLayout:
size_hint: 1,.1
orientation: "horizontal"
Button:
text:"1"
Button:
text:"2"
Button:
text:"3"
ScrollView:
GridLayout:
orientation: "vertical"
size_hint_y: None
height: self.minimum_height #<<<<<<<<<<<<<<<<<<<<
row_default_height: 60
cols:1
Button:
Button:
Button:
Button:
Button:
Button:
Button:
Button:
Button:
Button:
Button:
Button:
Button:
Button:
Button:
Button:
'''
class MyScreenManager(ScreenManager):
pass
class HomeScreen(Screen):
pass
class MyApp(App):
def build(self):
return HomeScreen()
def main():
Builder.load_string(kv_text)
app = MyApp()
app.run()
if __name__ == '__main__':
main()
Output:
I tried like #Ishinomori to recreate the app of #FJSevilla in pure Python3.7.
After a few changes I have done it!
# -*- coding: utf-8 -*-
# Kivy
from kivy.app import App
from kivy.uix.gridlayout import GridLayout
from kivy.uix.boxlayout import BoxLayout
from kivy.uix.scrollview import ScrollView
from kivy.uix.button import Button
from kivy.core.window import Window
class HomeScreen(BoxLayout):
def __init__(self, **kwargs):
# Initiate Box Layout and change orientation to vertical
super().__init__(**kwargs)
self.orientation = "vertical"
# Top Bar with Buttons "1", "2" & "3"
self.top_bar = BoxLayout(orientation="horizontal", size_hint=(1, .1))
self.top_bar.add_widget(Button(text="1"))
self.top_bar.add_widget(Button(text="2"))
self.top_bar.add_widget(Button(text="3"))
# Create the Gridlayout for the Scroll View and add height bounding
self.contend_scroll_view = GridLayout(size_hint_y=None, row_default_height=60, cols=1)
self.contend_scroll_view.bind(minimum_height=self.contend_scroll_view.setter('height'))
# 30 Dummy Buttons (real data here!)
for _ in range(30):
self.contend_scroll_view.add_widget(Button())
# Add the contend to the Scroll View
self.scroll_view = ScrollView()
self.scroll_view.add_widget(self.contend_scroll_view)
# Add the two Widgets to Home Screen
self.add_widget(self.top_bar)
self.add_widget(self.scroll_view)
class MyApp(App):
def build(self):
return HomeScreen()
if __name__ == '__main__':
# Only runs if file is executed directly, but not if importet
MyApp().run()
I'm starting with kivy and have some question. I'm have code with couple screens and buttons. How can I put one label with time or something like that on all of my screens? In the below code I created a screens but i don't wanna put 3 separate labels on the individual screens
main.py
from kivy.app import App
from kivy.lang import Builder
from kivy.uix.button import Button
from kivy.uix.widget import Widget
from kivy.properties import StringProperty, ObjectProperty
from kivy.clock import Clock
from kivy.uix.textinput import TextInput
from kivy.uix.screenmanager import ScreenManager, Screen
Builder.load_string("""
<StartScreen>:
BoxLayout:
orientation: 'vertical'
Button:
text: 'Start >'
size_hint_y: None
hight: '40dp'
on_press: root.manager.current = 'second'
<SecondScreen>:
BoxLayout:
orientation: 'vertical'
Button:
text: 'Test2'
size_hint_y: None
hight: '40dp'
on_press: root.manager.current = 'end'
<EndScreen>:
BoxLayout:
Button:
text: 'Test3'
size_hint_y: None
hight: '40dp'
on_press: root.manager.current = 'start'
""")
#declarate both screens
class StartScreen(Screen):
pass
class SecondScreen(Screen):
pass
class EndScreen(Screen):
pass
#create the screen manager
sm = ScreenManager()
sm.add_widget(StartScreen(name='start'))
sm.add_widget(SecondScreen(name='second'))
sm.add_widget(EndScreen(name='end'))
class TutorialApp(App):
def build(self):
return sm
if __name__ == '__main__':
TutorialApp().run()
This is one possible solution based on https://stackoverflow.com/a/18926863/6646710
The code below defines a label which displays the time.
import time
class IncrediblyCrudeClock(Label):
def __init__(self, **kwargs):
super(IncrediblyCrudeClock, self).__init__(**kwargs)
Clock.schedule_interval(self.update, 1)
def update(self, *args):
self.text = time.asctime()
The update function gets the current time from the python time module. The time is used to update the text property of the label. In the init method, the clock module is used to schedule calls to this update function each second.
Next I added this Label to all your kivy screens inside the kv string.
<StartScreen>:
BoxLayout:
orientation: 'vertical'
Button:
text: 'Start >'
size_hint_y: None
hight: '40dp'
on_press: root.manager.current = 'second'
IncrediblyCrudeClock:
<SecondScreen>:
BoxLayout:
orientation: 'vertical'
Button:
text: 'Test2'
size_hint_y: None
hight: '40dp'
on_press: root.manager.current = 'end'
IncrediblyCrudeClock:
<EndScreen>:
BoxLayout:
Button:
text: 'Test3'
size_hint_y: None
hight: '40dp'
on_press: root.manager.current = 'start'
IncrediblyCrudeClock:
The final result looks like that