'how to simply read barcode with kivy from camera and send the result to a method to process the barcode?
I would like to have a button on the screen that would open the camera and read a barcode and I would like to show the image of the product based on the barcode and if I press the button again It opens the camera again and does the same job.
Before asking here, I searched examples but couldn't make it working with my limited understanding of kivy.
I have tried using: https://github.com/kivy-garden/zbarcam It has following issues for my usecase.
- Camera is always open, would like to open only at button click
- Doesn't show the output of barcode not sure if it is reading or not.
- doesn't say what is the way to pass the output to a method so it can be processed further
Thanks in advance.
Solution 1:[1]
Unfortunately zbarcam of kivy-garden is designed in such away it will always keep the camera running in the background which heats up the device and consumes a lot of power.
Here is an implementation of zbarcam and qrcode that I have created earlier(username:admin ,password:admin). The actual implementation requests the username and password from Mysql database, let me know if you need that.
calc method can be used to get the qrcode string and display the image of the product.
Update
My implementation uses KivyMD here https://github.com/kivymd/KivyMD so you need to have it installed by using
pip install kivymd==0.104.1
It has QR generator from kivygarden here https://pypi.org/project/kivy-garden.qrcode/ you also need to have it installed.
pip install kivy-garden.qrcode
And of course you need pyzbar installed as it is a dependency for both packages
pip install pyzbar
demo.kv
#:import ZBarCam kivy_garden.zbarcam.ZBarCam
#:import ZBarSymbol pyzbar.pyzbar.ZBarSymbol
#:import QRCodeWidget kivy_garden.qrcode
MyLayout:
scr_mngr: scr_mngr
orientation: 'vertical'
ScreenManager:
id: scr_mngr
Screen:
id: screen1
name: 'screen1'
MDSpinner:
id:spinner
size_hint: None, None
size: dp(46), dp(46)
pos_hint: {'center_x': .5, 'center_y': .5}
active: False
MDToolbar:
md_bg_color: 0, 0, 1, 1
title: "Login Screen"
pos_hint:{"top": 1}
elevation: 11
BoxLayout:
orientation: "vertical"
padding: "16dp"
spacing: "16dp"
size_hint_y: None
height: self.minimum_height
pos_hint: {"center_y": .6}
MDLabel:
text: "Log In"
halign: "center"
font_style: "H4"
size_hint_y: None
MDTextField:
id: username
hint_text: "Username "
helper_text_mode: "on_focus"
required: True
MDTextField:
id: password
hint_text: "Password "
helper_text_mode: "on_focus"
required: True
password: True
MDRaisedButton:
text: "LOGIN"
pos_hint: {"center_x": 0.5, "center_y": 0.3}
on_release: root.check_data_login()
Screen:
id: screen2
name: 'screen2'
BoxLayout:
orientation: 'vertical'
MDToolbar:
md_bg_color: 0, 0, 1, 1
id: toolbar
title: "Page 2"
BoxLayout:
orientation: 'vertical'
MDTabs:
Tab:
text: "Scan"
ZBarCam:
id: zbarcam
# optional, by default checks all types
code_types: ZBarSymbol.QRCODE, ZBarSymbol.EAN13
pos_hint: {'center_x': 0.5, 'center_y': 0.75}
size_hint: [1, 1]
MDLabel:
id: qrlabel
#size_hint: None, None
size: self.texture_size[0], 50
pos_hint: {'center_x': 0.5, 'center_y': 0.3}
halign: "center"
text: ', '.join([str(symbol.data) for symbol in zbarcam.symbols])
on_text: root.calc(self.text)
opacity: 1
Tab:
text: "Generate"
BoxLayout:
orientation: 'vertical'
padding: "16dp"
spacing: "16dp"
MDTextField:
id: txtfld
pos_hint: {'center_x': 0.5, 'center_y': 0.75}
size_hint: [0.8,0.2]
hint_text: "Text to be encoded"
mode: "rectangle"
on_text: qr.data = txtfld.text
QRCodeWidget:
id: qr
data: ''
size_hint: [0.8,0.3]
pos_hint: {'center_x': 0.5, 'center_y': 0.3}
show_border: False
login.py
#!/usr/bin/env python
from kivymd.app import MDApp
from kivy.uix.boxlayout import BoxLayout
from kivy.uix.screenmanager import ScreenManager as scr_mngr
from kivymd.toast import toast
from kivy.core.window import Window
from kivymd.uix.tab import MDTabsBase
from kivy.uix.floatlayout import FloatLayout
class Tab(FloatLayout, MDTabsBase):
pass
class MyLayout(BoxLayout):
def check_data_login(self):
self.ids['spinner'].active=True
username = self.ids['username'].text
password = self.ids['password'].text
print(username)
print(password)
if not username and not password:
toast("Username and password are required")
elif not username:
toast("Username is required ")
elif not password:
toast("Password is required")
else:
if username == "admin" and password == "admin":
self.ids['spinner'].active=False
self.change_screen("screen2")
else:
self.ids['spinner'].active=False
toast("Wrong username or password")
def change_screen(self, screen, *args):
self.scr_mngr.current = screen
def calc(self, instance):
print(self.ids['qrlabel'].text)
class DemoApp(MDApp):
pass
if __name__ == '__main__':
Window.show_cursor = True
Window.size = (360, 680)
DemoApp().run()
Solution 2:[2]
I recently created a android qr code scanner app with ZBarCam. You can control the camera via the xcamera like this with ids. self.ids.<zbarcam_ids>.xcamera.play = True
I set it to false when the app is build and use screen manager to with on_enter/leave to enable/disble the camera.
Solution 3:[3]
I'm trying to do the same think, my way hope it helps:
try:
import kivy
from kivy.app import App
from kivy.uix.boxlayout import BoxLayout
from kivy.uix.image import Image
from kivy.uix.button import Button
from kivy.uix.label import Label
from kivy.uix.screenmanager import ScreenManager, Screen
from kivy_garden.zbarcam import ZBarCam
except:
import subprocess
subprocess.check_call(["python", '-m', 'pip', 'install', 'kivy'])
subprocess.check_call(["python", '-m', 'pip', 'install', 'kivy_garden'])
subprocess.check_call(["python", '-m', 'pip', 'install', 'pyzbar'])
class MainScreen(Screen):
def __init__(self, **kw):
super().__init__(**kw)
self.box = BoxLayout()
self.box.orientation = 'vertical'
self.box.spacing = 20
self.box.padding = 20
self.logo = Image(source='logo.png')
self.box.add_widget(self.logo)
self.btn_add_pick = Button(font_size=30, text='Add Pick')
self.box.add_widget(self.btn_add_qr)
self.btn_remove_pick = Button(font_size=30, text='Delet Pick')
self.box.add_widget(self.btn_remove_pick)
self.add_widget(self.box)
class CameraScreen(Screen):
def __init__(self, **kw):
super().__init__(**kw)
self.box = BoxLayout(orientation = 'vertical')
self.cam = ZBarCam()
self.cam.play = False
self.btn_close = Button(font_size=30, size_hint_y=None, text='Get')
self.box.add_widget(self.cam)
self.box.add_widget(self.btn_close)
self.add_widget(self.box)
class WindowManager(ScreenManager):
def __init__(self, **kv):
super().__init__(**kv)
ms = MainScreen(name="main")
ms.btn_add_pick.bind(on_press=self.switch_to_camera)
ms.btn_remove_pick.bind(on_press=self.switch_to_camera)
self.add_widget(ms)
cs = CameraScreen(name = "camera")
cs.btn_close.bind(on_press=self.switch_to_main)
self.add_widget(cs)
def switch_to_camera(self, instance):
self.current='camera'
self.transition.direction='down'
def switch_to_main(self, instance):
self.current = 'main'
self.transition.direction='up'
class WoodWQApp(App):
def build(self):
wm = WindowManager()
wm.current = 'main'
return wm
if __name__=="__main__":
WoodWQApp().run()
Sources
This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.
Source: Stack Overflow
| Solution | Source |
|---|---|
| Solution 1 | |
| Solution 2 | TEA |
| Solution 3 |

