I try to use uix.camera widget and show some wideo from my web-camera.
I looked into the documentation and try to use this simply code. But it's just show me a white creen withoud any video (I enabled playing).
What I'm doing wrong?
Maybe some useful docs\tutorial exist (because from official documentation I understanding a little from many). Thanks for any help.
import kivy
kivy.require('1.9.1')
from kivy.app import App
from kivy.uix.label import Label
from kivy.uix.camera import Camera
class MainApp(App):
def build(self):
return Camera(play=True)
if __name__== "__main__":
MainApp().run()
You need to specify resolution. In my case, I also needed to specify index=1, that is the second camera plugged in my computer.
Example:
import kivy
kivy.require('1.9.1')
from kivy.app import App
from kivy.uix.label import Label
from kivy.uix.camera import Camera
class MainApp(App):
def build(self):
return Camera(play=True, index=1, resolution=(640,480))
if __name__== "__main__":
MainApp().run()
It seems like you need to set resolution=[x, y] property besides play=True, because the default one doesn't work.
The following are the Kivy examples to use camera.
from kivy.app import App
from kivy.lang import Builder
kv = '''
BoxLayout:
orientation: 'vertical'
Camera:
id: camera
resolution: 399, 299
BoxLayout:
orientation: 'horizontal'
size_hint_y: None
height: '48dp'
Button:
text: 'Start'
on_release: camera.play = True
Button:
text: 'Stop'
on_release: camera.play = False
'''
class CameraApp(App):
def build(self):
return Builder.load_string(kv)
if __name__ == '__main__':
CameraApp().run()
Example 2:-
from kivy.app import App
from kivy.lang import Builder
from kivy.uix.boxlayout import BoxLayout
import time
Builder.load_string('''
<CameraClick>:
orientation: 'vertical'
Camera:
id: camera
resolution: (640, 480)
play: False
ToggleButton:
text: 'Play'
on_press: camera.play = not camera.play
size_hint_y: None
height: '48dp'
Button:
text: 'Capture'
size_hint_y: None
height: '48dp'
on_press: root.capture()
''')
class CameraClick(BoxLayout):
def capture(self):
'''
Function to capture the images and give them the names
according to their captured time and date.
'''
camera = self.ids['camera']
timestr = time.strftime("%Y%m%d_%H%M%S")
camera.export_to_png("IMG_" + timestr)
print("Captured")
class TestCamera(App):
def build(self):
return CameraClick()
TestCamera().run()
I just faced the same problem and found out that Kivy is very slow when creating widget for usb webcam device.
If you have set the index and other parameters properly, maybe just waiting a little longer for Kivy to create the video widget then you could see the webcam view shows in the window, but I am still trying to find out the reason why Kivy takes so long time (about a minute) to create usb webcam widget, hope someone could give some advices about this problem.
I tried using the code as suggested by #Thiago. It didnt work, I suspect its not detecting my USB camera that I have plugged into my Raspberry Pi4.
Following is the code I am using and I also ran a query in the terminal to obtain the camera type that is plugged in (only one plugged in).
The Code:
import kivy
from kivy.app import App
from kivy.uix.label import Label
from kivy.uix.camera import Camera
class MainApp(App):
def build(self):
return Camera(play=True, index=0, resolution=(640,480))
if __name__== "__main__":
MainApp().run()
Terminal Output:
pi#raspberrypi:~ $ v4l2-ctl --list-formats
ioctl: VIDIOC_ENUM_FMT
Type: Video Capture
[0]: 'MJPG' (Motion-JPEG, compressed)
[1]: 'YUYV' (YUYV 4:2:2)
Related
Im working on an mobile calculator app. Please be aware that this is my first own project.
The app should be able to offer a simple calc advanceded and should display different functions.
I achive this with the BottomNavigation but the file gets huge. Any troubleshooting is not possible at least not for me.
with the screenmanager I could separate the different screens into different files but I cannot do this BottomNavigator.
Could Anybody give me a hint please.
working with the screenmanager
found it just in case anybody doesnt know either:
#main.py
from kivy.lang import Builder
from kivymd.app import MDApp
from kivy.uix.screenmanager import ScreenManager, Screen
from kivymd.uix.bottomnavigation.bottomnavigation import MDBottomNavigationItem
class MainApp(MDApp):
def build(self):
self.theme_cls.theme_style = "Dark"
self.theme_cls.primary_palette = "BlueGray"
return Builder.load_file("my.kv")
MainApp().run()
#my.kv
#:include advanced_calc_screen.kv
BoxLayout:
orientation: "vertical"
MDBottomNavigationItem:
name: "advanced_calc"
text: "advanced"
icon: "calculator"
Advanced:
#advanced_calc_screen.kv
<Advanced>:
Button:
text: "You are at Homescreen"
I have a project where I need to integrate a hardware barcode scanner built into an Android Barcode scanning Device (Cipherlab). My app is built and the only part outstanding is reading the barcode. The barcodes are terminated by an enter keycode. The enter keys are being detected but the rest of the barcode does not display in the textinput which has focus.
I have tested the scanner in a text editor and it's not that. So it looks like the text is being scanned in the app as the enter keycode triggers the on_text_validate event.
Any ideas would be greatly appreciated.
main.py
from kivy.app import App
from kivy.lang import Builder
from kivy.clock import Clock
from kivy.uix.screenmanager import ScreenManager, Screen
Builder.load_string('''
<MainScreen>:
text_in: text_in
memberStatus: memberStatus
BoxLayout:
orientation: 'vertical'
Label:
id: memberStatus
TextInput:
id: text_in
multiline: False
on_text_validate:
root.process_barcode()
''')
class MainScreen(Screen):
def process_barcode(self):
self.memberStatus.text = "Read Value:"+ self.text_in.text
self.text_in.text = ""
Clock.schedule_once(lambda *args: setattr(self.text_in, 'focus', True))
def on_enter(self):
self.memberStatus.text = "Text Input has focus"
Clock.schedule_once(lambda *args: setattr(self.text_in, 'focus', True))
class MyApp(App):
def build(self):
sm = ScreenManager()
sm.add_widget(MainScreen(name="screen_main"))
return sm
if __name__ == '__main__':
MyApp().run()
I just started using Python Kivy
I have this two files
# main.py
from kivy.app import App
from kivy.uix.button import Button
from kivy.uix.boxlayout import BoxLayout
class Container(BoxLayout):
pass
class MyApp(App):
def build(self):
return Container()
if __name__ == '__main__':
MyApp().run()
and
# My.kv
<Container>:
orientation: 'vertical'
padding: 50
spacing: 25
Button:
size: 100, 100
size_hint: None, None
text: 'Hello'
Button:
text: 'World'
everything works on Windows, but I need Linux to build it.
if I run the same files on Ubuntu 18.04, I will get a black screen. When working without .kv there is no such problem, all widgets are displayed.
What's the matter?
Your My.kv should be named my.kv. Since Windows doesn't care about upper/lower case in file names, it works there.
This is camera code
Camera Example
==============
This example demonstrates a simple use of the camera. It shows a window with
a buttoned labelled 'play' to turn the camera on and off. Note that
not finding a camera, perhaps because gstreamer is not installed, will
throw an exception during the kv language processing.
'''
# Uncomment these lines to see all the messages
# from kivy.logger import Logger
# import logging
# Logger.setLevel(logging.TRACE)
from kivy.app import App
from kivy.lang import Builder
from kivy.uix.boxlayout import BoxLayout
import time
Builder.load_string('''
<CameraClick>:
orientation: 'vertical'
Camera:
id: camera
resolution: (640, 480)
play: False
ToggleButton:
text: 'Play'
on_press: camera.play = not camera.play
size_hint_y: None
height: '48dp'
Button:
text: 'Capture'
size_hint_y: None
height: '48dp'
on_press: root.capture()
''')
class CameraClick(BoxLayout):
def capture(self):
'''
Function to capture the images and give them the names
according to their captured time and date.
'''
camera = self.ids['camera']
#timestr = time.strftime("%Y%m%d_%H%M%S")
camera.export_to_png("IMG_{}.png".format(timestr))
print("Captured")
class TestCamera(App):
def build(self):
return CameraClick()
TestCamera().run()
I want to save captured image in my current directory with a name like img.png instead of saving image name with a timestamp.
This code saves image with name like IMG_20200216_162830 and I want it like IMG.png
Can anyone help me?
Thank you
Remove the timestamp, that's all:
camera.export_to_png("IMG.png")
as stated in the title - I'm stuck. I've been playing with the code around and everything works as long as I keep ScreenManager and Popup separate. Once combined - they refuse to cooperate. Anyway, here is the simple app that shows the problem I'm having.
from kivy.lang import Builder
from kivy.app import App
from kivy.uix.gridlayout import GridLayout
from kivy.uix.popup import Popup
from kivy.uix.screenmanager import Screen, ScreenManager
class First(GridLayout,Screen):
def show_popup(self):
Popp().open()
pass
class Second(Screen):
pass
class Popp(Popup):
pass
class ScreenManagement(ScreenManager):
pass
app = Builder.load_file("main.kv")
class MainApp(App):
def build(self):
return app
if __name__ == "__main__":
MainApp().run()
And main.kv file
ScreenManagement:
First:
Second:
<First>:
name:"First"
rows: 2
Button:
text: "FirstButton"
on_release: app.root.current = "Second"
Button:
text: "Show popup"
on_release: root.show_popup()
<Second>:
name:"Second"
Button:
text: "BUTTON"
on_release: app.root.current = "First"
<Popp>:
title: "testing"
text: "Hello world"
size_hint: None,None
size: 400,400
auto_dismiss: False
Button:
text: "Okay"
on_press: root.dismiss()
App starts, first and second screen are working but when trying to get popup up I end up with:
kivy.uix.popup.PopupException: Popup can have only one widget as content
Somehow Screen is seen as a widget inside of Popp? Or am I terribly misinterpreting kivy docs?
It's a bug with loading kv file, it should throw an exception in this case.
What you are doing in the code is loading the kv file twice, what causes some weird behavior. Just delete the Builder.load_file(..) and it will work. The file is going to be loaded automatically.
Also, never do double subclassing of widgets like class First(GridLayout, Screen) as it might lead to some problems. Instead, create a grid layout inside the screen.
Put the elements in the Popup inside a layout, for example: Boxlayout.
Here's what I mean:
<Popp>:
title: "testing"
BoxLayout:
orientation: 'vertical'
size_hint: None,None
size: 400,400
Label:
text: "Hello world"
Button:
text: "Okay"
on_press: root.dismiss()
I have same problem with using kivy Builder.load_file and Popup, they dont work together.
the solution is simple, build popup in python code side. this is a loading popup example:
python:
from kivy.app import App
from kivy.uix.popup import Popup
from kivy.factory import Factory
from kivy.properties import ObjectProperty
from kivy.clock import Clock
from kivy.lang import Builder
from kivy.uix.popup import Popup
from kivy.uix.image import Image
from kivy.uix.label import Label
from kivy.uix.boxlayout import BoxLayout
import time, threading
buildKV = Builder.load_file("example.kv")
class ExampleApp(App):
def show_popup(self):
content = BoxLayout(orientation= "vertical")
image=Image(source= 'files/loading.gif', anim_delay= 0)
label=Label(text= 'Model is Running.\nBe Patient Please.')
content.add_widget(image)
content.add_widget(label)
self.popup = Popup(title='Model is Running.',
size_hint=(.250, .785),
content=content, auto_dismiss=False)
self.popup.open()
def process_button_click(self):
# Open the pop up
self.show_popup()
# Call some method that may take a while to run.
# I'm using a thread to simulate this
mythread = threading.Thread(target=self.something_that_takes_5_seconds_to_run)
mythread.start()
def something_that_takes_5_seconds_to_run(self):
thistime = time.time()
while thistime + 10 > time.time(): # 5 seconds
time.sleep(1)
# Once the long running task is done, close the pop up.
self.pop_up.dismiss()
if __name__ == "__main__":
ExampleApp().run()
kivy:
BoxLayout:
Button:
height: 40
width: 100
size_hint: (None, None)
text: 'Click Me'
on_press: app.process_button_click()