Convert python to kivy language - python

I am new to python and more to kivy, with this it turns out that they helped me to create this code (below), it turns out that after my code seems to work well, many told me that for good practices I did not write I will create graphic environments with python that existed for that .kv, with this clearer it turns out that I have not been able to achieve how I do it, I hope you could help me to transcribe it I thank you from the bottom of my heart thank you, below the code, I just want to transcribe what I have thanks.
# -*- coding: utf-8 -*-
from kivy.app import App
from kivy.uix.boxlayout import BoxLayout
from kivy.uix.image import Image
from kivy.graphics.texture import Texture
from kivy.clock import Clock
import cv2
class CvCamera(App):
def build(self): # Construcción de interfaz de usuario, etc
self._cap = cv2.VideoCapture(0)
layout2 = BoxLayout(orientation='horizontal', size_hint=(1.0, 0.1))
self.img1 = Image(size_hint=(1.0, 0.7))
layout = BoxLayout(orientation='vertical')
layout.add_widget(self.img1)
layout.add_widget(layout2)
while not self._cap.isOpened():
pass
Clock.schedule_interval(self.update, 1.0 / 30.0)
return layout
def update(self, dt):
ret, img = self._cap.read()
img = cv2.flip(img, 0)
texture1 = Texture.create(size=(img.shape[1], img.shape[0]), colorfmt='bgr')
texture1.blit_buffer(img.tostring(), colorfmt='bgr', bufferfmt='ubyte')
self.img1.texture = texture1
if __name__ == '__main__':
CvCamera().run()

Here is the equivalent using kv language:
# -*- coding: utf-8 -*-
from kivy.app import App
from kivy.lang import Builder
from kivy.graphics.texture import Texture
from kivy.clock import Clock
import cv2
kv = '''
BoxLayout:
orientation: 'vertical'
Image:
id: img1
size_hint: 1.0, 0.7
BoxLayout:
orientation: 'horizontal'
size_hint: 1.0, 0.1
'''
class CvCamera(App):
def build(self): # Construcción de interfaz de usuario, etc
self._cap = cv2.VideoCapture(0)
layout = Builder.load_string(kv)
while not self._cap.isOpened():
pass
Clock.schedule_interval(self.update, 1.0 / 30.0)
return layout
def update(self, dt):
ret, img = self._cap.read()
img = cv2.flip(img, 0)
texture1 = Texture.create(size=(img.shape[1], img.shape[0]), colorfmt='bgr')
texture1.blit_buffer(img.tostring(), colorfmt='bgr', bufferfmt='ubyte')
self.root.ids.img1.texture = texture1
if __name__ == '__main__':
CvCamera().run()
Note that, in general, the arguments in () of the Widgets become entries below and indented from the Widget name.

Related

Kivy with cv2 in python (Read barcode)

i try to make app for read barcode using android machine and i have problem i cant compare between cv and kivy please if someone can help me .
code that read barcode from android camera using kivy
from kivy.app import App
from kivy.uix.camera import Camera
from pyzbar.pyzbar import decode
import numpy as np
import cv2
from kivy.properties import ListProperty
class MainApp(App):
def build(self):
self.capture = cv2.VideoCapture(0)
cam = Camera(play=True, resolution=(640, 480))
#cap=cv2.VideoCapture(0)
success, frame=self.read()
for code in decode(frame):
print(code.type)
print(code.data.decode('utf-8'))
cv2.imshow("Results", frame);
cv2.waitKey(1);
return cam
if __name__== "__main__":
MainApp().run()
what do you mean by " i cant compare between cv and kivy" ? I have working machine learning app in kivy using cam. So what do you exactly need ? You need o display img in cv window, or you want to display camera frames in kivy ? You can update the kivy window every x second:
def __init__(self, **kw):
super().__init__()
self.capture = None
def on_pre_enter(self, *args):
super().__init__()
self.capture = cv.VideoCapture(0)
Clock.schedule_interval(self.update, 1.0 / 30) # update 30 fps
def on_leave(self, *args):
self.capture.release()
And then you can display frame as kivy image texture like this:
def update(self, dt):
ret, frame = self.capture.read()
if ret:
buf1 = cv.flip(frame, 0)
buf = buf1.tobytes()
image_texture = Texture.create(
size=(frame.shape[1], frame.shape[0]), colorfmt='bgr')
image_texture.blit_buffer(buf, colorfmt='bgr', bufferfmt='ubyte')
self.ids['image'].texture = image_texture
And Image you can define in kivy:
MDBoxLayout:
size_hint: .65,1
orientation: 'vertical'
Image: #webcam
id: image

How to run python / pytube code on iOS device?

I built a simple app using pytube with which you can download Youtube videos.
That's the code:
from kivy.app import App
from kivy.uix.gridlayout import GridLayout
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 pytube import YouTube
import os
class AVPlayer(App):
def build(self):
self.window = GridLayout()
self.window.cols = 1
self.user = TextInput(
padding_y = (20, 20),
size_hint = (1, 0.5),
)
self.window.add_widget(self.user)
self.window.size_hint = (0.6, 0.2)
self.window.pos_hint = {"center_x": 0.5, "center_y": 0.5}
self.button = Button(
text="Download",
size_hint = (1, 0.5),
background_color = '#398AFF'
)
self.button.bind(on_press=self.callback)
self.window.add_widget(self.button)
return self.window
def callback(self, event):
url = self.user.text
my_video = YouTube(url)
#get Video Title
print("*********************Video Title************************")
print(my_video.title)
#get Thumbnail Image
print("********************Tumbnail Image***********************")
print(my_video.thumbnail_url)
#download
print("********************Download video*************************")
#my_video = my_video.streams.get_highest_resolution().download()
my_video = my_video.streams.filter(res="360p").first().download()
if __name__ == "__main__":
AVPlayer().run()
It just runs on my desktop. But I would like to have it as a mobile app on my iPhone. I could create an iOS app using swift but there is no library like pytube.
I guess kivy would be possible, too, but I do not like it.. so is there an other alternative?

How to add a background video in Kivy

I am new to Kivy and I am sort of stuck. I am using GridLayout to make my app and I am having some trouble putting a video in my background. The code I will post makes an app with a black background. How do I replace the black background with a video, particularly mp4. I would also like to make the video darker if possible. I wanted to use AnchorPoint but I am not quite sure how to put both in there. Any help will be appreciated.
from kivy.app import App
from kivy.uix.video import Video
from kivy.uix.floatlayout import FloatLayout
from kivy.uix.gridlayout import GridLayout
from kivy.uix.label import Label
from kivy.uix.image import Image
from kivy.uix.button import Button
from kivy.uix.textinput import TextInput
class MZ_Invest(App):
def build(self):
self.root_layout = FloatLayout()
self.window = GridLayout()
self.window.cols = 1
self.window.size_hint = (0.6,0.7)
self.window.pos_hint = {"center_x":0.5, "center_y":0.5}
#add widgets
#Video
video = Video(source='birds.mp4', state='play')
video.opacity = 0.5
#Image
self.window.add_widget(Image(
source="mzi.png",
size_hint = (1.5,1.5)
))
#Label
self.greeting = Label(
text="How much would you like to invest?",
font_size = 18,
color='90EE90'
)
self.window.add_widget(self.greeting)
#User Input
self.user = TextInput(
multiline=False,
padding_y= (20,20),
size_hint = (1, 0.5)
)
self.window.add_widget(self.user)
#Button
self.button = Button(
text="Submit",
size_hint = (1,0.5),
bold = True,
background_color = '90EE90',
)
self.button.bind(on_press=self.callback)
self.window.add_widget(self.button)
#self.root_layout.add_widget(video)
self.root_layout.add_widget(self.window)
return self.root_layout
def callback(self, instance):
if self.user.text.isnumeric() and int(self.user.text) >= 10000:
self.greeting.text = "Calculating: $" + self.user.text
self.greeting.color = '90EE90'
else:
self.greeting.text = "Invalid"
self.greeting.color = "#FF0000"
if __name__ == "__main__":
MZ_Invest().run()
Most Kivy widgets have a transparent background, so you can just display a video and then display your GUI over that. Try adding something like this at the end of your build() method:
self.root_layout = FloatLayout()
video = Video(source='BigBuckBunny.mp4', state='play')
video.opacity = 0.5 # adjust to make the video lighter/darker
self.root_layout.add_widget(video) # add the video first
self.root_layout.add_widget(self.window) # now add the GUI window so it will be drawn over the video
return self.root_layout # return the root_layout instead of the window

Kivy + Python + Raspberry - How to implement countdown

I'm quite new to python programming and I'm currently building a photobooth using Kivy and Python.
In general it is working (I can press the button and it starts the function to take 3 pictures and updates the tumbnail on the screen) , but I'm not able to change the label text (actionLabel) to show a countdown before the takePhotos function starts.
import os, time, Image, sys, datetime, subprocess,glob
import kivy
kivy.require('1.10.0') # replace with your current kivy version !
from kivy.app import App
from kivy.uix.button import Button
from kivy.uix.gridlayout import GridLayout
from kivy.uix.label import Label
from kivy.uix.image import Image as kivyImage
from kivy.clock import Clock
from kivy.graphics import Color, Rectangle
import RPi.GPIO as GPIO
#GPIO varialbes
#buttonPin = 23
GPIO.setmode(GPIO.BCM)
GPIO.setup(23,GPIO.IN)
GPIO_status = False
# Some variables
photoTitle = "My first Photobox!"
total_photos = 3 #Number of photos to be takes
#Function for photo taking
def takePhotos():
#Take first picture - Folder for inbound pictures /home/pi/PB_Inbox/photobooth%H%M%S.jpg
time.sleep(3)
subprocess.call("gphoto2 --capture-image-and-download --filename /home/pi/PB_Inbox/photobooth%H%M%S.jpg", shell=True)
#Take all other picture
for x in range (0,total_photos-1):
subprocess.call("gphoto2 --capture-image-and-download --filename /home/pi/PB_Inbox/photobooth%H%M%S.jpg", shell=True)
#Process pictures
subprocess.call("sudo sh /home/pi/Documents/Photo_Booth/Image_prep_3", shell=True)
print('done')
class MyApp(App):
# Display the latest thumbnail
photo = kivyImage(source="/home/pi/PB_Thumb/Thumb.png")
actionLabel = Label(text="Push the button", size_hint=(1, 0.2),color=[1,0,0,1],font_size='40sp')
def build(self):
# Set up the layout
photobox = GridLayout(rows=3, spacing=10, padding=10)
# Create the UI objects (and bind them to callbacks, if necessary)
headerLabel = Label(text="The Greatest Photobox", size_hint=(1, 0.1),font_size='40sp') # Button: 20% width, 100% height
# Add the UI elements to the layout
photobox.add_widget(headerLabel)
photobox.add_widget(self.photo)
photobox.add_widget(self.actionLabel)
# Periodically refresh the displayed photo using the callback function
Clock.schedule_interval(self.callback, 0.3)
return photobox
# Callback for thumbnail refresh and listening to GPIO for input
def callback(self, instance):
self.photo.reload()
if self.readSensor() == False:
pass
#print('waiting')
else:
#provided as an argument
takePhotos()
#Read status of the sensor and return True if Buzzer has been pushed
def readSensor(self):
sensor = GPIO.input(23)
if sensor == 1:
return True
else:
return False
if __name__ == '__main__':
MyApp().run()
Can someone show me how to do this?
Thx
Use Clock.create_trigger to trigger the count down.
Remove the time.sleep(3) in function, takePhotos().
Use Clock.schedule_once to invoke function takePhotos() i.e. Clock.schedule_once(takePhotos, 3)
Separate the Kivy App into Python Script and kv file.
Programming Guide » Events and Properties
In Kivy applications, you have to avoid long/infinite loops or sleeping.
Example
main.py
import os, time, sys, datetime, subprocess, glob
from kivy.app import App
from kivy.uix.boxlayout import BoxLayout
from kivy.clock import Clock
from kivy.properties import ObjectProperty, NumericProperty
import RPi.GPIO as GPIO
# GPIO variables
# buttonPin = 23
GPIO.setmode(GPIO.BCM)
GPIO.setup(23, GPIO.IN)
GPIO_status = False
# Some variables
total_photos = 3 # Number of photos to be takes
# Function for photo taking
def takePhotos(dt):
# Take 3 picture
for x in range(total_photos):
subprocess.call("gphoto2 --capture-image-and-download --filename /home/pi/PB_Inbox/photobooth%H%M%S.jpg", shell=True)
# Process pictures
subprocess.call("sudo sh /home/pi/Documents/Photo_Booth/Image_prep_3", shell=True)
print('done')
class PhotoBox(BoxLayout):
photo = ObjectProperty(None)
action_button = ObjectProperty(None)
count_down_trigger = ObjectProperty(None)
count = NumericProperty(3)
def __init__(self, **kwargs):
super(PhotoBox, self).__init__(**kwargs)
# Display the latest thumbnail
self.photo.source = "/home/pi/PB_Thumb/Thumb.png"
self.count_down_trigger = Clock.create_trigger(self.count_down, 1)
def on_press_camera_button(self):
self.count = 3
self.count_down_trigger()
def count_down(self, dt):
self.action_button.text = str(self.count)
self.count -= 1
if self.count >= 0:
self.count_down_trigger()
else:
self.action_button.text = "Say Cheese!"
# Periodically refresh the displayed photo using the callback function
# Clock.schedule_interval(self.callback, 0.3) # infinite loop
Clock.schedule_once(self.callback, 0.3)
self.action_button.text = "Push the button" # reset text
# Callback for thumbnail refresh and listening to GPIO for input
def callback(self, dt):
self.photo.reload()
if self.readSensor():
# provided as an argument
Clock.schedule_once(takePhotos, 3) # call takePhotos method once after 3 seconds
else:
pass
#print('waiting')
# Read status of the sensor and return True if Buzzer has been pushed
def readSensor(self):
sensor = True # GPIO.input(23)
if sensor == 1:
return True
else:
return False
class MyApp(App):
title = "My first Photobox!"
def build(self):
return PhotoBox()
if __name__ == '__main__':
MyApp().run()
my.kv
#:kivy 1.10.0
<PhotoBox>:
photo: photo
action_button: action_button
orientation:'vertical'
spacing: 10
padding: 10
Label:
text: "The Greatest Photobox"
size_hint: (1, 0.1)
font_size: '40sp'
AsyncImage:
id: photo
Button:
id: action_button
text: "Push the button"
size_hint: (1, 0.2)
color: [1,0,0,1]
font_size: '40sp'
on_press: root.on_press_camera_button()
Output

Kivy accordion interaction

I have images loading in the kivy accordion and I want to print out the x and y coordinates below the images when I press the mouse button. I can't for the life of my figure this out. Every time I add anything it seems like it shuts the whole program down. I know that the widget I have will print to the console but I want to print it to the screen.
Here is the code I am using:
from kivy.uix.accordion import Accordion, AccordionItem
from kivy.uix.image import Image
from kivy.app import App
from kivy.uix.widget import Widget
class MouseWidget(Widget):
def on_touch_down(self, touch):
print(touch)
class MyApp(App):
def build(self):
root = Accordion(orientation='horizontal')
item= AccordionItem(title='Picture1')
src = "picture1.png"
image = Image(source=src,pos=(200, 100))
# add image to AccordionItem
item.add_widget(image)
root.add_widget(item)
item= AccordionItem(title='Picture2')
src = "picture2.png"
image = Image(source=src,pos=(200, 100))
# add image to AccordionItem
item.add_widget(image)
root.add_widget(item)
return root
if __name__ == '__main__':
MyApp().run()
Here's a simple modification to your program that adds the touch position to a label below the image, using kivy language to automatically bind to the necessary properties so that the display is updated when they change.
I'm not sure what problems you had in particular, so let me know if the way it works is not clear!
from kivy.uix.accordion import Accordion, AccordionItem
from kivy.uix.image import Image
from kivy.app import App
from kivy.uix.widget import Widget
from kivy.lang import Builder
from kivy.properties import ObjectProperty, StringProperty
from kivy.uix.boxlayout import BoxLayout
Builder.load_string('''
<MouseWidget>:
image: image
label: label
orientation: 'vertical'
Image:
id: image
source: root.source
Label:
id: label
size_hint_y: None
height: 50
text: 'no touch detected'
''')
class MouseWidget(BoxLayout):
image = ObjectProperty()
label = ObjectProperty()
source = StringProperty()
def on_touch_down(self, touch):
if self.image.collide_point(*touch.pos):
self.label.text = str(touch.pos)
def on_touch_up(self, touch):
self.label.text = 'no touch detected'
class MyApp(App):
def build(self):
root = Accordion(orientation='horizontal')
item= AccordionItem(title='Picture1')
src = "picture1.png"
image = MouseWidget(source=src)
# add image to AccordionItem
item.add_widget(image)
root.add_widget(item)
item= AccordionItem(title='Picture2')
src = "picture2.png"
image = MouseWidget(source=src)
# add image to AccordionItem
item.add_widget(image)
root.add_widget(item)
return root
if __name__ == '__main__':
MyApp().run()
Every time I add anything it seems like it shuts the whole program down.
This sounds like your changes crashed the program. You should check the output of your program by running it in a terminal. It will print information about the error that can help you track down your mistakes.

Categories

Resources