add qrcodereader
This commit is contained in:
parent
e9d449e0b6
commit
ddc20bedac
@ -65,6 +65,7 @@ from .login import LoginForm
|
|||||||
if platform == 'android':
|
if platform == 'android':
|
||||||
from .widgetExt.phonebutton import PhoneButton
|
from .widgetExt.phonebutton import PhoneButton
|
||||||
from .widgetExt.androidwebview import AWebView
|
from .widgetExt.androidwebview import AWebView
|
||||||
|
from .widgetExt.camera import AndroidCamera
|
||||||
|
|
||||||
class Text(BGColorBehavior, Label):
|
class Text(BGColorBehavior, Label):
|
||||||
def __init__(self,bgcolor=[],fgcolor=[],color_level=-1,**kw):
|
def __init__(self,bgcolor=[],fgcolor=[],color_level=-1,**kw):
|
||||||
|
@ -78,10 +78,8 @@ class BGColorBehavior(object):
|
|||||||
|
|
||||||
def selected(self):
|
def selected(self):
|
||||||
self.bgcolor = self.selected_bgcolor
|
self.bgcolor = self.selected_bgcolor
|
||||||
Logger.info('selected:color=%s',self.bgcolor)
|
|
||||||
self.on_bgcolor()
|
self.on_bgcolor()
|
||||||
|
|
||||||
def unselected(self):
|
def unselected(self):
|
||||||
self.bgcolor = self.normal_bgcolor
|
self.bgcolor = self.normal_bgcolor
|
||||||
Logger.info('unselected:color=%s',self.bgcolor)
|
|
||||||
self.on_bgcolor()
|
self.on_bgcolor()
|
||||||
|
@ -119,9 +119,7 @@ class BoxViewer(BoxLayout):
|
|||||||
blocks = Factory.Blocks()
|
blocks = Factory.Blocks()
|
||||||
blocks.bind(on_built=partial(doit,self,holders,index))
|
blocks.bind(on_built=partial(doit,self,holders,index))
|
||||||
blocks.bind(on_failed=doerr)
|
blocks.bind(on_failed=doerr)
|
||||||
print('showObject():********here***********')
|
|
||||||
blocks.widgetBuild(options, ancestor=self)
|
blocks.widgetBuild(options, ancestor=self)
|
||||||
print('showObject():********end ***********')
|
|
||||||
|
|
||||||
def on_scroll_stop(self,o,v=None):
|
def on_scroll_stop(self,o,v=None):
|
||||||
if o.scroll_y <= 0.001:
|
if o.scroll_y <= 0.001:
|
||||||
|
@ -14,7 +14,7 @@ class HostImage(Image):
|
|||||||
super().__init__(**kwargs)
|
super().__init__(**kwargs)
|
||||||
self.downloadImage(url)
|
self.downloadImage(url)
|
||||||
|
|
||||||
def downloadImage(url):
|
def downloadImage(self,url):
|
||||||
realurl = absurl(url,self.target.parenturl)
|
realurl = absurl(url,self.target.parenturl)
|
||||||
loader = HTTPDataHandler(url,stream=True)
|
loader = HTTPDataHandler(url,stream=True)
|
||||||
loader.bind(on_success=self.createTmpfile)
|
loader.bind(on_success=self.createTmpfile)
|
||||||
@ -25,9 +25,10 @@ class HostImage(Image):
|
|||||||
self.source = blockImage('broken.png')
|
self.source = blockImage('broken.png')
|
||||||
|
|
||||||
def createTmpfile(self,o,resp):
|
def createTmpfile(self,o,resp):
|
||||||
fn = tempfile.NamedTemporaryFile(delete=True)
|
fn = tempfile.mkstemp()[1]
|
||||||
|
print('************fn=%s',fn)
|
||||||
with open(fn, 'wb') as f:
|
with open(fn, 'wb') as f:
|
||||||
for chunk in r.iter_content(chunk_size=8192):
|
for chunk in resp.iter_content(chunk_size=8192):
|
||||||
if chunk: # filter out keep-alive new chunks
|
if chunk: # filter out keep-alive new chunks
|
||||||
f.write(chunk)
|
f.write(chunk)
|
||||||
# f.flush()
|
# f.flush()
|
||||||
|
@ -54,6 +54,7 @@ class PageContainer(FloatLayout):
|
|||||||
w = self.pageWidgets[-1]
|
w = self.pageWidgets[-1]
|
||||||
self.pageWidgets = self.pageWidgets[:-1]
|
self.pageWidgets = self.pageWidgets[:-1]
|
||||||
self.showLastPage()
|
self.showLastPage()
|
||||||
|
if hasattr(w,'__del__'):
|
||||||
w.__del__()
|
w.__del__()
|
||||||
|
|
||||||
def add_widget(self,widget):
|
def add_widget(self,widget):
|
||||||
|
63
kivyblocks/qrcodereader.py
Normal file
63
kivyblocks/qrcodereader.py
Normal file
@ -0,0 +1,63 @@
|
|||||||
|
import numpy as np
|
||||||
|
import cv2
|
||||||
|
from kivy.app import App
|
||||||
|
from kivy.core.window import Window
|
||||||
|
from kivy.graphics.texture import Texture
|
||||||
|
from kivy.uix.image import Image
|
||||||
|
from kivy.clock import Clock
|
||||||
|
|
||||||
|
class QRCodeReader(Image):
|
||||||
|
def __init__(self, **kwargs):
|
||||||
|
super().__init__(**kwargs)
|
||||||
|
self.register_event_type('on_data')
|
||||||
|
self.opened = False
|
||||||
|
self.task = None
|
||||||
|
|
||||||
|
def open(self):
|
||||||
|
self.opened = True
|
||||||
|
self.cam = cv2.VideoCapture(0)
|
||||||
|
self.detector = cv2.QRCodeDetector()
|
||||||
|
self.task = Clock.schedule_interval(self.read,1.0/30.0)
|
||||||
|
Window.add_widget(self)
|
||||||
|
|
||||||
|
def on_data(self,d):
|
||||||
|
print('QRCodeReader().on_data(),data=',d)
|
||||||
|
self.dismiss()
|
||||||
|
|
||||||
|
def on_touch_down(self,touch):
|
||||||
|
if not self.colide_point(*touch.pos):
|
||||||
|
self.dismiss()
|
||||||
|
super().on_touch_down(touch)
|
||||||
|
|
||||||
|
def dismiss(self):
|
||||||
|
if not self.opened:
|
||||||
|
return
|
||||||
|
self.opened = False
|
||||||
|
self.task.cancel()
|
||||||
|
self.task = None
|
||||||
|
self.cam.release()
|
||||||
|
cv2.destroyAllWindows()
|
||||||
|
Window.remove_widget(self)
|
||||||
|
|
||||||
|
def showImage(self,img):
|
||||||
|
image = np.rot90(np.swapaxes(img,0,1))
|
||||||
|
tex = Texture.create(size=(image.shape[1], image.shape[0]),
|
||||||
|
colorfmt='rgb')
|
||||||
|
tex.blit_buffer(image.tostring(),colorfmt='rgb', bufferfmt='ubyte')
|
||||||
|
self.texture = tex
|
||||||
|
|
||||||
|
def read(self,p):
|
||||||
|
_, img = self.cam.read()
|
||||||
|
self.showImage(img)
|
||||||
|
data,bbox,_ = self.detector.detectAndDecode(img)
|
||||||
|
if data:
|
||||||
|
self.dispatch('on_data',data)
|
||||||
|
|
||||||
|
if __name__ == '__main__':
|
||||||
|
class MyApp(App):
|
||||||
|
def build(self):
|
||||||
|
r = QRCodeReader()
|
||||||
|
return r
|
||||||
|
myapp = MyApp()
|
||||||
|
myapp.run()
|
||||||
|
|
@ -4,6 +4,7 @@ from .tree import Tree, TextTree, PopupMenu
|
|||||||
from .toolbar import ToolPage, Toolbar
|
from .toolbar import ToolPage, Toolbar
|
||||||
from .dg import DataGrid
|
from .dg import DataGrid
|
||||||
from .vplayer import VPlayer
|
from .vplayer import VPlayer
|
||||||
|
from .aplayer import APlayer
|
||||||
from .form import Form, StrSearchForm
|
from .form import Form, StrSearchForm
|
||||||
from .boxViewer import BoxViewer
|
from .boxViewer import BoxViewer
|
||||||
from .pagescontainer import PageContainer
|
from .pagescontainer import PageContainer
|
||||||
@ -38,6 +39,8 @@ r('Tree',Tree)
|
|||||||
r('TextTree',TextTree)
|
r('TextTree',TextTree)
|
||||||
r('PopupMenu',PopupMenu)
|
r('PopupMenu',PopupMenu)
|
||||||
r('HostImage',HostImage)
|
r('HostImage',HostImage)
|
||||||
|
r('APlayer',APlayer)
|
||||||
if platform == 'android':
|
if platform == 'android':
|
||||||
r('PhoneButton',PhoneButton)
|
r('PhoneButton',PhoneButton)
|
||||||
r('AWebView',AWebView)
|
r('AWebView',AWebView)
|
||||||
|
r('AndroidCamera',AndroidCamera)
|
||||||
|
83
kivyblocks/swipebehavior.py
Normal file
83
kivyblocks/swipebehavior.py
Normal file
@ -0,0 +1,83 @@
|
|||||||
|
import time
|
||||||
|
from kivy.logger import Logger
|
||||||
|
from kivy.event import EventDispatcher
|
||||||
|
|
||||||
|
class SwipeBehavior(EventDispatcher):
|
||||||
|
def __init__(self, **kwargs):
|
||||||
|
self.register_event_type('on_context_menu')
|
||||||
|
self.register_event_type('on_swipe_left')
|
||||||
|
self.register_event_type('on_swipe_right')
|
||||||
|
self.register_event_type('on_swipe_up')
|
||||||
|
self.register_event_type('on_swipe_down')
|
||||||
|
self.sb_start_point = None
|
||||||
|
self.sb_end_point = None
|
||||||
|
self.sb_start_time = None
|
||||||
|
self.sb_end_time = None
|
||||||
|
self.threshold=20
|
||||||
|
self.threshold_time = 1.5
|
||||||
|
|
||||||
|
def on_context_menu(self):
|
||||||
|
Logger.info('SwipeBehavior:on_context_menu fired')
|
||||||
|
|
||||||
|
def on_swipe_left(self):
|
||||||
|
Logger.info('SwipeBehavior:on_swipe_left fired')
|
||||||
|
pass
|
||||||
|
|
||||||
|
def on_swipe_right(self):
|
||||||
|
Logger.info('SwipeBehavior:on_swipe_right fired')
|
||||||
|
pass
|
||||||
|
|
||||||
|
def on_swipe_up(self):
|
||||||
|
Logger.info('SwipeBehavior:on_swipe_up fired')
|
||||||
|
pass
|
||||||
|
|
||||||
|
def on_swipe_down(self):
|
||||||
|
Logger.info('SwipeBehavior:on_swipe_down fired')
|
||||||
|
pass
|
||||||
|
|
||||||
|
def on_touch_down(self,touch):
|
||||||
|
if self.collide_point(*touch.pos):
|
||||||
|
self.sb_start_point = pos
|
||||||
|
self.sb_start_time = time.time()
|
||||||
|
return super().on_touch_down(touch)
|
||||||
|
|
||||||
|
def on_touch_move(self,touch):
|
||||||
|
if self.collide_point(*touch.pos):
|
||||||
|
if self.sb_start_point is None:
|
||||||
|
self.sb_start_point = touch.pos
|
||||||
|
else:
|
||||||
|
self.sb_end_point = touch.pos
|
||||||
|
return super().on_touch_move()
|
||||||
|
|
||||||
|
def on_touch_up(self,touch):
|
||||||
|
if self.collide_point(*touch.pos):
|
||||||
|
self.sb_end_point = touch.pos
|
||||||
|
self.sb_end_time = time.time()
|
||||||
|
self.check_context_menu()
|
||||||
|
self.check_swipe()
|
||||||
|
self.sb_start_point = None
|
||||||
|
self.sb_end_point = None
|
||||||
|
self.sb_start_time = None
|
||||||
|
self.sb_end_time = None
|
||||||
|
super().on_touch_up()
|
||||||
|
|
||||||
|
def check_context_menu(self):
|
||||||
|
if not self.sb_start_time:
|
||||||
|
return
|
||||||
|
if not self.sb_end_time:
|
||||||
|
return
|
||||||
|
if self.sb_end_time - self.sb_start_time > self.threshold_time:
|
||||||
|
self.dispatch('on_context_menu')
|
||||||
|
|
||||||
|
def check_swipe(self):
|
||||||
|
if abs(self.sb_end_point.x - self.sb_start_point.x) > \
|
||||||
|
abs(self.sb_end_point.y - self.sb_start_point.y):
|
||||||
|
if self.sb_end_point.x - self.sb_start_point.x > self.threshold:
|
||||||
|
self.dispatch('on_swipe_right')
|
||||||
|
elif self.sb_start_point.x - self.sb_end_point.x > self.threshold:
|
||||||
|
self.dispatch('on_swipe_left')
|
||||||
|
else:
|
||||||
|
if self.sb_end_point.y - self.sb_start_point.y > self.threshold:
|
||||||
|
self.dispatch('on_swipe_up')
|
||||||
|
elif self.sb_start_point.y - self.sb_end_point.x > self.threshold:
|
||||||
|
self.dispatch('on_swipe_down')
|
@ -23,6 +23,7 @@ from ffpyplayer.tools import set_log_callback
|
|||||||
from .utils import *
|
from .utils import *
|
||||||
from .paging import PageLoader
|
from .paging import PageLoader
|
||||||
from .baseWidget import PressableImage
|
from .baseWidget import PressableImage
|
||||||
|
from .swipebehavior import SwipeBehavior
|
||||||
|
|
||||||
desktopOSs=[
|
desktopOSs=[
|
||||||
"win",
|
"win",
|
||||||
@ -47,10 +48,11 @@ class UrlPlayList(PageLoader):
|
|||||||
id = d['rows'][0].id
|
id = d['rows'][0].id
|
||||||
self.player.play(id)
|
self.player.play(id)
|
||||||
|
|
||||||
class BaseVPlayer(FloatLayout):
|
class BaseVPlayer(FloatLayout, SwipeBehavior):
|
||||||
fullscreen = BooleanProperty(False)
|
fullscreen = BooleanProperty(False)
|
||||||
def __init__(self,vfile=None,playlist=[]):
|
def __init__(self,vfile=None,playlist=[]):
|
||||||
super().__init__()
|
FloatLayout.__init__(self)
|
||||||
|
SwipeBehavior.__init__(self)
|
||||||
self.register_event_type('on_source_error')
|
self.register_event_type('on_source_error')
|
||||||
self.register_event_type('on_next')
|
self.register_event_type('on_next')
|
||||||
self.register_event_type('on_previous')
|
self.register_event_type('on_previous')
|
||||||
@ -70,6 +72,18 @@ class BaseVPlayer(FloatLayout):
|
|||||||
if hasattr(self._video._video, '_ffplayer'):
|
if hasattr(self._video._video, '_ffplayer'):
|
||||||
self.ffplayer = self._video._video._ffplayer
|
self.ffplayer = self._video._video._ffplayer
|
||||||
|
|
||||||
|
def on_swipe_down(self):
|
||||||
|
self.stop()
|
||||||
|
self.dispatch('on_next')
|
||||||
|
|
||||||
|
on_swipe_right = on_swipe_down
|
||||||
|
|
||||||
|
def on_swipe_up(self):
|
||||||
|
self.stop()
|
||||||
|
self.dispatch('on_previous')
|
||||||
|
|
||||||
|
on_swipe_left = on_swipe_up
|
||||||
|
|
||||||
def setSource(self,s):
|
def setSource(self,s):
|
||||||
self.stop()
|
self.stop()
|
||||||
self.curplay = 0
|
self.curplay = 0
|
||||||
@ -104,9 +118,11 @@ class BaseVPlayer(FloatLayout):
|
|||||||
self._video.state = 'play'
|
self._video.state = 'play'
|
||||||
|
|
||||||
def next(self,o=None,v=None):
|
def next(self,o=None,v=None):
|
||||||
|
self.stop()
|
||||||
self.dispatch('on_next',self)
|
self.dispatch('on_next',self)
|
||||||
|
|
||||||
def previous(self,o=None,v=None):
|
def previous(self,o=None,v=None):
|
||||||
|
self.stop()
|
||||||
self.dispatch('on_previous',self)
|
self.dispatch('on_previous',self)
|
||||||
|
|
||||||
def on_state(self,o=None,v=None):
|
def on_state(self,o=None,v=None):
|
||||||
@ -307,12 +323,18 @@ class VPlayer(BaseVPlayer):
|
|||||||
self.slider.max = self._video.duration
|
self.slider.max = self._video.duration
|
||||||
self.maxposition.text = self.totime(self._video.duration)
|
self.maxposition.text = self.totime(self._video.duration)
|
||||||
|
|
||||||
|
def stop(self):
|
||||||
|
if self.update_task is not None:
|
||||||
|
self.update_task.cancel()
|
||||||
|
self.update_task = None
|
||||||
|
super().stop()
|
||||||
|
|
||||||
def __del__(self):
|
def __del__(self):
|
||||||
self.beforeDestroy()
|
self.beforeDestroy()
|
||||||
|
|
||||||
def beforeDestroy(self):
|
def beforeDestroy(self):
|
||||||
print('beforeDestroy() called')
|
print('beforeDestroy() called')
|
||||||
self._video.state = 'stop'
|
self.stop()
|
||||||
return True
|
return True
|
||||||
|
|
||||||
def show_hide_menu(self,obj,touch):
|
def show_hide_menu(self,obj,touch):
|
||||||
|
@ -23,67 +23,33 @@ class AndroidCamera(Camera):
|
|||||||
intent.putExtra(MediaStore.EXTRA_OUTPUT, parcelable)
|
intent.putExtra(MediaStore.EXTRA_OUTPUT, parcelable)
|
||||||
activity.startActivityForResult(intent, 0x123)
|
activity.startActivityForResult(intent, 0x123)
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
def _take_video(self, on_complete, filename=None):
|
def _take_video(self, on_complete, filename=None):
|
||||||
|
|
||||||
assert(on_complete is not None)
|
assert(on_complete is not None)
|
||||||
|
|
||||||
self.on_complete = on_complete
|
self.on_complete = on_complete
|
||||||
|
|
||||||
self.filename = filename
|
self.filename = filename
|
||||||
|
|
||||||
android.activity.unbind(on_activity_result=self._on_activity_result)
|
android.activity.unbind(on_activity_result=self._on_activity_result)
|
||||||
|
|
||||||
android.activity.bind(on_activity_result=self._on_activity_result)
|
android.activity.bind(on_activity_result=self._on_activity_result)
|
||||||
|
|
||||||
intent = Intent(MediaStore.ACTION_VIDEO_CAPTURE)
|
intent = Intent(MediaStore.ACTION_VIDEO_CAPTURE)
|
||||||
|
|
||||||
uri = Uri.parse('file://' + filename)
|
uri = Uri.parse('file://' + filename)
|
||||||
|
|
||||||
parcelable = cast('android.os.Parcelable', uri)
|
parcelable = cast('android.os.Parcelable', uri)
|
||||||
|
|
||||||
intent.putExtra(MediaStore.EXTRA_OUTPUT, parcelable)
|
intent.putExtra(MediaStore.EXTRA_OUTPUT, parcelable)
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
# 0 = low quality, suitable for MMS messages,
|
# 0 = low quality, suitable for MMS messages,
|
||||||
|
|
||||||
# 1 = high quality
|
# 1 = high quality
|
||||||
|
|
||||||
intent.putExtra(MediaStore.EXTRA_VIDEO_QUALITY, 1)
|
intent.putExtra(MediaStore.EXTRA_VIDEO_QUALITY, 1)
|
||||||
|
|
||||||
activity.startActivityForResult(intent, 0x123)
|
activity.startActivityForResult(intent, 0x123)
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
def _on_activity_result(self, requestCode, resultCode, intent):
|
def _on_activity_result(self, requestCode, resultCode, intent):
|
||||||
|
|
||||||
if requestCode != 0x123:
|
if requestCode != 0x123:
|
||||||
|
|
||||||
return
|
return
|
||||||
|
|
||||||
android.activity.unbind(on_activity_result=self._on_activity_result)
|
android.activity.unbind(on_activity_result=self._on_activity_result)
|
||||||
|
|
||||||
if self.on_complete(self.filename):
|
if self.on_complete(self.filename):
|
||||||
|
|
||||||
self._remove(self.filename)
|
self._remove(self.filename)
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
def _remove(self, fn):
|
def _remove(self, fn):
|
||||||
|
|
||||||
try:
|
try:
|
||||||
|
|
||||||
remove(fn)
|
remove(fn)
|
||||||
|
|
||||||
except OSError:
|
except OSError:
|
||||||
|
|
||||||
pass
|
pass
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
def instance():
|
def instance():
|
||||||
return AndroidCamera()
|
return AndroidCamera()
|
||||||
|
Loading…
Reference in New Issue
Block a user