add qrcodereader

This commit is contained in:
yumoqing 2020-04-27 16:48:55 +08:00
parent e9d449e0b6
commit ddc20bedac
10 changed files with 181 additions and 45 deletions

View File

@ -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):

View File

@ -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()

View File

@ -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:

View File

@ -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()

View File

@ -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):

View 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()

View File

@ -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)

View 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')

View File

@ -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):

View File

@ -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()