A clock with kivy python - python

I would like to display the time with kivy. I don't want that the label use the whole page. How can I do ?
I want it to appear the same as in the following photo:
from kivy.app import App
from datetime import datetime
from datetime import timedelta
from kivy.clock import Clock
from kivy.uix.label import Label
class myApp(App):
def build(self):
self.now = datetime.now()
# Schedule the self.update_clock function to be called once a second
Clock.schedule_interval(self.update_clock, 1)
self.my_label = Label(text= self.now.strftime('%H:%M:%S'))
return self.my_label # The label is the only widget in the interface
def update_clock(self, *args):
# Called once a second using the kivy.clock module
# Add one second to the current time and display it on the label
self.now = self.now + timedelta(seconds = 1)
self.my_label.text = self.now.strftime('%H:%M:%S')
myApp().run()

Related

How Can I Animate a Label in Kivy?

Ok, My question goes this way How Can I Animate a Label in Kivy, My apologies if this question is annoyingly way too easy :)
Here is the Label in which I want animation. Can I have edits of the code in the comments?
Actually, I am obsessed with this script, racking my brains off to know the way to animate this thingy!! Pls Help!..
import kivy
from kivy.app import App
from kivy.uix.label import Label
class MyApp(App):
def build(self):
lu = Label(text = "This is a label! Pls help me with Animation!")
return lu
if __name__ == '__main__':
MyApp().run()
If you want to update text on Label every few seconds then you can use Clock and Clock.schedule_interval(function_name, seconds) to execute function_name(dt) every seconds and in this function you should change text in Label
Minimal example which displays current time.
from kivy.app import App
from kivy.uix.label import Label
from kivy.clock import Clock
import datetime
def update_label(dt):
new_text = datetime.datetime.now().strftime('%H:%M:%S')
label.text = new_text
#print(new_text)
label = None # create global variable to access the same `label` in two different functions
class MyApp(App):
def build(self):
global label # inform function to assign `Label` to global variable
label = Label(text="???")
Clock.schedule_interval(update_label, 1)
return label
#Clock.schedule_interval(update_label, 1)
if __name__ == '__main__':
MyApp().run()
EDIT:
Another example which scroll text
from kivy.app import App
from kivy.uix.label import Label
from kivy.clock import Clock
import datetime
label = None
text = 'Hello World of Python!'
text_length = len(text)
index = 0
temp_text = text + ' ' + text
def update_label(dt):
global index
label.text = temp_text[index:index+15]
index += 1
if index >= text_length:
index = 0
class MyApp(App):
def build(self):
global label
label = Label(text="???")
Clock.schedule_interval(update_label, 0.20)
return label
if __name__ == '__main__':
MyApp().run()
EDIT:
For numerical values you can use Animation.
Here is blinking text.
It changes color to black (in 0.2 second) and next it change back to white (in 0.2 second). And it repeats it.
from kivy.app import App
from kivy.uix.label import Label
from kivy.animation import Animation
class MyApp(App):
def build(self):
label = Label(text='Hello World of Python!')
anim = Animation(color=(0, 0, 0, 1), duration=.2) + Animation(color=(1, 1, 1, 1), duration=.2)
anim.repeat = True
anim.start(label)
return label
if __name__ == '__main__':
MyApp().run()

python/kivy: need function clock() but crash because of recursion

I'm new to python and kivy and try to learn from code snippets and trial and error. But now I'm stuck.
To displays weather and garbage information on an raspberry I used kivy.
To grab these information I use the function URLRequest. This function needs the clock-function
while not req.is_finished:
Clock.tick()
return req.result
So the program works, displays the infos but crashed regularly after some 20 minutes or so wit hthe error "RuntimeError: maximum recursion depth exceeded
But I don't understand how I can get rid of the recursion by still getting things working :(
Here's mor of the code in context. Can anyone help?
# -*- coding: utf-8 -*-
from kivy.app import App
from kivy.uix.label import Label
from kivy.clock import Clock
from kivy.uix.button import Button
from kivy.uix.boxlayout import BoxLayout
from kivy.uix.label import Label
from kivy.uix.widget import Widget
from kivy.uix.textinput import TextInput
from kivy.network.urlrequest import UrlRequest
from time import gmtime, strftime, localtime, sleep
class garbage:
def garbage_text(garbage):
req = UrlRequest('http://192.168.1.1:8083/fhem?cmd={ReadingsVal(%22ABFALL%22,%22next_text%22,0)}&XHR=1&fwcsrf=password')
while not req.is_finished:
Clock.tick()
return req.result
class weather:
def weather_db1(weather):
req = UrlRequest('http://192.168.1.1:8083/fhem?cmd={ReadingsVal(%22netatmo_M01_00_00_3f_1d_1a%22,%22temperature%22,0)}&XHR=1&fwcsrf=password')
while not req.is_finished:
Clock.tick()
return req.result
class MyBox(BoxLayout):
def update(self, *args):
uweather = weather()
aktw = uweather.weather_db1()
ggarbage = garbage()
garbagetext = ggarbage.garbage_text()
self.ids.temp_ist.text = str(aktw)
self.ids.uhrzeit_top.text = strftime("%H:%M", localtime())
self.ids.datum_top.text = strftime("%d.%m.%Y", localtime())
self.ids.garbage_std.text = garbagetext+" rausstellen "
class ControlApp(App):
def build(self):
actclock = MyBox()
Clock.schedule_interval(actclock.update, 1)
return actclock
if __name__ == "__main__":
ControlApp().run()
Here is a modified version of your code that uses callbacks instead of looping or waiting:
from kivy.app import App
from kivy.lang import Builder
from kivy.clock import Clock, mainthread
from kivy.uix.boxlayout import BoxLayout
from kivy.network.urlrequest import UrlRequest
from time import strftime, localtime
class garbage:
def garbage_text(self, *args):
req = UrlRequest('http://192.168.1.1:8083/fhem?cmd={ReadingsVal(%22netatmo_M01_00_00_3f_1d_1a%22,%22temperature%22,0)}&XHR=1&fwcsrf=password',
on_success=self.update, on_failure=self.failure)
#mainthread
def update(self, req, result):
# update the GUI
garbage_std = App.get_running_app().root.ids.garbage_std
garbage_std.text = str(result)+" rausstellen "
# schedule the next update
Clock.schedule_once(self.garbage_text, 1)
def failure(self):
print('garbage failed')
class weather:
def weather_db1(self, *args):
req = UrlRequest('http://192.168.1.1:8083/fhem?cmd={ReadingsVal(%22netatmo_M01_00_00_3f_1d_1a%22,%22temperature%22,0)}&XHR=1&fwcsrf=password',
on_success=self.update, on_failure=self.failure)
#mainthread
def update(self, req, result):
# update the GUI
temp_ist = App.get_running_app().root.ids.temp_ist
temp_ist.text = str(result)
# schedule the next update
Clock.schedule_once(self.weather_db1, 1)
def failure(self):
print('weather failed')
class MyBox(BoxLayout):
def update(self, *args):
self.ids.uhrzeit_top.text = strftime("%H:%M", localtime())
self.ids.datum_top.text = strftime("%d.%m.%Y", localtime())
class ControlApp(App):
def build(self):
actclock = MyBox()
self.weather = weather()
self.garbage = garbage()
# start the time updates
Clock.schedule_interval(actclock.update, 1)
# start the other updates
Clock.schedule_once(self.weather_update)
Clock.schedule_once(self.garbage_update)
return actclock
def weather_update(self, dt):
self.weather.weather_db1()
def garbage_update(self, dt):
self.garbage.garbage_text()
Builder.load_string('''
<MyBox>:
orientation: 'vertical'
Label:
id: temp_ist
Label:
id: uhrzeit_top
Label:
id: datum_top
Label:
id: garbage_std
''')
if __name__ == "__main__":
ControlApp().run()

Kivy Product Search Program

from kivy.app import App
from kivy.uix.label import Label
from kivy.uix.gridlayout import GridLayout
from kivy.uix.textinput import TextInput
from kivy.uix.button import Button
from kivy.uix.screenmanager import ScreenManager, Screen
import json
import re
class Grid(GridLayout):
def __init__(self, **kwargs):
super(Grid, self).__init__(**kwargs)
# Columns for the main view
self.cols = 1
# Start of the Inside
self.inside = GridLayout()
self.inside.rows = 3
self.inside.add_widget(Label(text = 'Enter the Brand Name for its Products: '))
self.brand_input = TextInput(multiline = False)
self.inside.add_widget(self.brand_input)
# Add the things in inside to the main
self.add_widget(self.inside)
self.submit = Button(text = 'Submit', font_size = 20)
self.submit.bind(on_press = self.pressed)
self.add_widget(self.submit)
def pressed(self, instance):
# Pull the text inside the textInput
brand_name = self.brand_input.text
with open('mcg_app/brands.json', 'r') as f:
brands_dict = json.load(f)
request = brands_dict[brand_name]
modified_result = re.sub(r',\s(?![^(]*\))', "\n", str(request))
self.inside.add_widget(Label(text = modified_result))
# Clear out the fields after submitting
self.brand_input.text = ''
class Mcg(App):
def build(self):
return Grid()
if __name__ == '__main__':
Mcg().run()
Hello, this program here has a text input box and the user inputs a brand name for example "Dove" after that he presses the submit button, and the button is connected to the pressed() function. Everything about the program is actually working fine the only problem is after I print the products of the entered brand let's say he inputs a different brand in that case the old output is still there so the program outputs new products with the old ones already there. How can I fix this? Thanks in advance
I can't really test it without a json data file, but check out this:
from kivy.app import App
from kivy.uix.label import Label
from kivy.uix.gridlayout import GridLayout
from kivy.uix.textinput import TextInput
from kivy.uix.button import Button
import json
import re
class Grid(GridLayout):
def __init__(self, **kwargs):
super(Grid, self).__init__(**kwargs)
# Columns for the main view
self.cols = 1
# Start of the Inside
self.inside = GridLayout()
self.inside.rows = 3
self.inside.add_widget(Label(text='Enter the Brand Name for its Products: '))
self.brand_input = TextInput(multiline=False)
self.inside.add_widget(self.brand_input)
# Add the things in inside to the main
self.add_widget(self.inside)
self.submit = Button(text='Submit', font_size=20)
self.submit.bind(on_press=self.pressed)
self.add_widget(self.submit)
def pressed(self, instance):
# Clear out the fields after submitting
self.brand_input.text = ''
self.inside.clear_widgets()
self.inside.add_widget(Label(text='Enter the Brand Name for its Products: '))
self.inside.add_widget(self.brand_input)
# Pull the text inside the textInput
brand_name = self.brand_input.text
with open('mcg_app/brands.json', 'r') as f:
brands_dict = json.load(f)
request = brands_dict[brand_name]
modified_result = re.sub(r',\s(?![^(]*\))', "\n", str(request))
self.inside.add_widget(Label(text=modified_result))
class Mcg(App):
def build(self):
return Grid()
if __name__ == '__main__':
Mcg().run()
It resets the self.inside GridLayout on every button press...

How to output text and delete text with buttons

I'm trying to output text from button presses and add it to a textbox each time it's pressed as well as delete the text when the delete button is pressed - in normal python.
I've been trying to use kivy.uix.textinput, but I'm not sure on how to output the value from the buttons as well as delete it.
This is what I've done so far.
from kivy.app import App
from kivy.uix.screenmanager import Screen
from kivy.uix.button import Button
from kivy.uix.boxlayout import BoxLayout
from kivy.uix.gridlayout import GridLayout
from kivy.uix.textinput import TextInput
class CodeScreen(Screen):
def __init__(self):
super(CodeScreen, self).__init__(name='code_screen')
main_grid_lay = GridLayout(cols=2,cols_minimum={0:640, 1:175})
self.add_widget(main_grid_lay)
#Code ouput display
display_code = TextInput(text='Code!', readonly = True, id=output)
main_grid_lay.add_widget(display_code)
#Options Buttons
box_lay = BoxLayout(orientation='vertical')
main_grid_lay.add_widget(box_lay)
delete_button = Button(
text='Delete',
size_hint_x= None,
width=160,
id='' #unsure on how to delete
)
box_lay.add_widget(delete_button)
base_left = Button(
text='Base Left',
#on_release= b_left(),
#id='left',
)
base_right = Button(
text='Base Right',
on_release=self.degree_popup,
#on_release= b_right(),
)
#b_left = self.ids.output.text='left'
#b_left = self.ids.output.text='right'
box_lay.add_widget(base_left)
box_lay.add_widget(base_right)
# The app class
class MyMain(App):
def build(self):
return CodeScreen()
# Runs the App
if __name__ == '__main__':
MyMain().run()
It currently sends an error and is probably because of the ids. Not fully sure how ids work without using kv language. Any help is appreciated.
The id only makes sense in .kv, in python they are useless. In this case the solution is to access the objects in the methods connected to on_release but for this they must be class attributes.
from kivy.app import App
from kivy.uix.screenmanager import Screen
from kivy.uix.button import Button
from kivy.uix.boxlayout import BoxLayout
from kivy.uix.gridlayout import GridLayout
from kivy.uix.textinput import TextInput
class CodeScreen(Screen):
def __init__(self):
super(CodeScreen, self).__init__(name="code_screen")
self.display_code = TextInput(text="Code!", readonly=True)
self.delete_button = Button(
text="Delete", size_hint_x=None, width=160, on_release=self.delete_clicked
)
self.base_left = Button(text="Base Left", on_release=self.left_clicked)
self.base_right = Button(text="Base Right", on_release=self.right_clicked)
main_grid_lay = GridLayout(cols=2, cols_minimum={0: 640, 1: 175})
main_grid_lay.add_widget(self.display_code)
self.add_widget(main_grid_lay)
box_lay = BoxLayout(orientation="vertical")
box_lay.add_widget(self.delete_button)
main_grid_lay.add_widget(box_lay)
box_lay.add_widget(self.base_left)
box_lay.add_widget(self.base_right)
def delete_clicked(self, instance):
self.display_code.text = ""
def left_clicked(self, instance):
self.display_code.text += "left"
def right_clicked(self, instance):
self.display_code.text += "right"
# The app class
class MyMain(App):
def build(self):
return CodeScreen()
# Runs the App
if __name__ == "__main__":
MyMain().run()

Kivy/Python Countdown App project kivy has no attribute 'built' error

Question: What is a 'has no attribute 'built' error, and what do I need to do to correct this code so that it can take in a datetime object and display the count down? Sorry for the long post.
I've provided the code and a link to the .kv file.
I tried to create a countdown clock that takes a datetime object as a parameter and counts down to that date (using python and kivy). It's basically an slight adaptation of Adam Giermanowski's countdown timer tutorial.
Here's my code:
from kivy.app import App
from kivy.uix.label import Label
from kivy.uix.boxlayout import BoxLayout
from kivy.properties import StringProperty
from kivy.clock import Clock
import datetime
#datetime object
b= datetime.datetime(2016,9,12,3,5)
class Counter_Timer(BoxLayout):
days = StringProperty()
hours = StringProperty()
minutes = StringProperty()
seconds = StringProperty()
def __init__(self, datetimeOBJ):
self.datetimeOBJ = datetimeOBJ
def update(self, dt):
#the difference in time
delta = self.datetimeOBJ - datetime.datetime.now()
self.days = str(delta.days)
hour_string = str(delta).split(', ')[1]
self.hours = hour_string.split(':')[0]
self.minutes = hour_string.split(':')[1]
self.seconds = hour_string.split(':')[2].split('.')[0]
class Counter(App):
#takes a datetime object as a parameter
def __init__(self, datetimeOBJ):
self.datetimeOBJ = datetimeOBJ
def build(self):
Counter = Counter_Timer(self.datetimeOBJ)
Clock.schedule_interval(Counter.update, 1.0)
return Counter
if __name__=='__main__':
Counter(b).run()
Here's the error on the Counter(b).run() line:
AttributeError: 'Counter' object has no attribute 'built'
You have to call the superclasses constructor when you override __init__, so that all of the things that that constructor does in order to have the other methods of the class work gets done. Your init method should be this:
def __init__(self, datetimeOBJ):
App.init(self)
self.datetimeOBJ = datetimeOBJ

Categories

Resources