kivy: fix qrcodewidget (only update from gui thread)

This commit is contained in:
ThomasV 2015-12-13 16:21:50 +01:00
parent a190d1dbe6
commit f7ffdfc2b1
3 changed files with 7 additions and 30 deletions

View file

@ -42,14 +42,9 @@ Builder.load_string('''
class QRCodeWidget(FloatLayout): class QRCodeWidget(FloatLayout):
data = StringProperty(None, allow_none=True) data = StringProperty(None, allow_none=True)
background_color = ListProperty((1, 1, 1, 1)) background_color = ListProperty((1, 1, 1, 1))
foreground_color = ListProperty((0, 0, 0, 0)) foreground_color = ListProperty((0, 0, 0, 0))
#loading_image = StringProperty('gui/kivy/theming/loading.gif')
def __init__(self, **kwargs): def __init__(self, **kwargs):
super(QRCodeWidget, self).__init__(**kwargs) super(QRCodeWidget, self).__init__(**kwargs)
self.data = None self.data = None
@ -57,21 +52,11 @@ class QRCodeWidget(FloatLayout):
self._qrtexture = None self._qrtexture = None
def on_data(self, instance, value): def on_data(self, instance, value):
print "on data", value
if not (self.canvas or value): if not (self.canvas or value):
return return
img = self.ids.get('qrimage', None)
if not img:
# if texture hasn't yet been created delay the texture updation
Clock.schedule_once(lambda dt: self.on_data(instance, value))
return
#Thread(target=partial(self.update_qr, )).start()
self.update_qr() self.update_qr()
def set_data(self, data): def set_data(self, data):
print "set data", data
if self.data == data: if self.data == data:
return return
MinSize = 210 if len(data) < 128 else 500 MinSize = 210 if len(data) < 128 else 500
@ -98,7 +83,7 @@ class QRCodeWidget(FloatLayout):
# currently unused, do we need this? # currently unused, do we need this?
self._texture_size = size self._texture_size = size
def _create_texture(self, k, dt): def _create_texture(self, k):
self._qrtexture = texture = Texture.create(size=(k,k), colorfmt='rgb') self._qrtexture = texture = Texture.create(size=(k,k), colorfmt='rgb')
# don't interpolate texture # don't interpolate texture
texture.min_filter = 'nearest' texture.min_filter = 'nearest'
@ -107,32 +92,24 @@ class QRCodeWidget(FloatLayout):
def update_texture(self): def update_texture(self):
if not self.qr: if not self.qr:
return return
matrix = self.qr.get_matrix() matrix = self.qr.get_matrix()
k = len(matrix) k = len(matrix)
# create the texture in main UI thread otherwise # create the texture
# this will lead to memory corruption self._create_texture(k)
Clock.schedule_once(partial(self._create_texture, k), -1)
buff = [] buff = []
bext = buff.extend bext = buff.extend
cr, cg, cb, ca = self.background_color[:] cr, cg, cb, ca = self.background_color[:]
cr, cg, cb = cr*255, cg*255, cb*255 cr, cg, cb = cr*255, cg*255, cb*255
for r in range(k): for r in range(k):
for c in range(k): for c in range(k):
bext([0, 0, 0] if matrix[r][c] else [cr, cg, cb]) bext([0, 0, 0] if matrix[r][c] else [cr, cg, cb])
# then blit the buffer # then blit the buffer
buff = ''.join(map(chr, buff)) buff = ''.join(map(chr, buff))
# update texture in UI thread. # update texture
Clock.schedule_once(lambda dt: self._upd_texture(buff), .1) self._upd_texture(buff)
def _upd_texture(self, buff): def _upd_texture(self, buff):
texture = self._qrtexture texture = self._qrtexture
if not texture:
# if texture hasn't yet been created delay the texture updation
Clock.schedule_once(lambda dt: self._upd_texture(buff), .1)
return
texture.blit_buffer(buff, colorfmt='rgb', bufferfmt='ubyte') texture.blit_buffer(buff, colorfmt='rgb', bufferfmt='ubyte')
img =self.ids.qrimage img =self.ids.qrimage
img.anim_delay = -1 img.anim_delay = -1

View file

@ -308,7 +308,7 @@ class ReceiveScreen(CScreen):
@profiler @profiler
def update_qr(self): def update_qr(self):
uri = self.get_URI() uri = self.get_URI()
qr = self.screen.ids.get('qr') qr = self.screen.ids.qr
qr.set_data(uri) qr.set_data(uri)
def do_copy(self): def do_copy(self):

View file

@ -42,7 +42,7 @@
color: .699, .699, .699, 1 color: .699, .699, .699, 1
font_size: '13sp' font_size: '13sp'
shorten: True shorten: True
text: root.message if root.message else ' ' text: root.message
Widget Widget
CardLabel: CardLabel:
halign: 'right' halign: 'right'