commit d99855f06072c33cef144edce68acded561e339a
parent 90464b6ac1be7db46365c4ffff7163631305b06d
Author: ThomasV <thomasv@electrum.org>
Date: Fri, 17 Feb 2017 20:56:38 +0100
use ctypes to access the zbar library
Diffstat:
4 files changed, 49 insertions(+), 39 deletions(-)
diff --git a/gui/qt/main_window.py b/gui/qt/main_window.py
@@ -2001,7 +2001,7 @@ class ElectrumWindow(QMainWindow, MessageBoxMixin, PrintError):
def read_tx_from_qrcode(self):
from electrum import qrscanner
try:
- data = qrscanner.scan_qr(self.config)
+ data = qrscanner.scan_barcode(self.config.get_video_device())
except BaseException as e:
self.show_error(str(e))
return
@@ -2517,9 +2517,9 @@ class ElectrumWindow(QMainWindow, MessageBoxMixin, PrintError):
#combo.addItem("Manually specify a device", config.get("video_device"))
index = qr_combo.findData(self.config.get("video_device"))
qr_combo.setCurrentIndex(index)
- msg = _("Install the zbar package to enable this.\nOn linux, type: 'apt-get install python-zbar'")
+ msg = _("Install the zbar package to enable this.")
qr_label = HelpLabel(_('Video Device') + ':', msg)
- qr_combo.setEnabled(qrscanner.zbar is not None)
+ qr_combo.setEnabled(qrscanner.libzbar is not None)
on_video_device = lambda x: self.config.set_key("video_device", str(qr_combo.itemData(x).toString()), True)
qr_combo.currentIndexChanged.connect(on_video_device)
gui_widgets.append((qr_label, qr_combo))
diff --git a/gui/qt/qrtextedit.py b/gui/qt/qrtextedit.py
@@ -49,12 +49,12 @@ class ScanQRTextEdit(ButtonsTextEdit, MessageBoxMixin):
def qr_input(self):
from electrum import qrscanner, get_config
try:
- data = qrscanner.scan_qr(get_config())
+ data = qrscanner.scan_barcode(get_config().get_video_device())
except BaseException as e:
self.show_error(str(e))
- return ""
+ data = ''
if type(data) != str:
- return
+ data = ''
self.setText(data)
return data
diff --git a/lib/qrscanner.py b/lib/qrscanner.py
@@ -24,43 +24,42 @@
# SOFTWARE.
import os
-from i18n import _
-
-try:
- import zbar
-except ImportError:
- zbar = None
-
-proc = None
+import sys
+from ctypes import cdll, c_char_p
+if sys.platform == 'darwin':
+ name = 'libzbar.dylib'
+elif sys.platform == 'windows':
+ name = 'libzbar.dll'
+else:
+ name = 'libzbar.so.0'
-def scan_qr(config):
- global proc
- if not zbar:
- raise RuntimeError("\n".join([_("Cannot start QR scanner."),_("The zbar package is not available."),_("On Linux, try 'sudo pip install zbar'")]))
- if proc is None:
- device = config.get("video_device", "default")
- if device == 'default':
- device = ''
- _proc = zbar.Processor()
- _proc.init(video_device=device)
- # set global only if init did not raise an exception
- proc = _proc
+try:
+ libzbar = cdll.LoadLibrary(name)
+except OSError:
+ libzbar = None
- proc.visible = True
- while True:
- try:
- proc.process_one()
- except Exception:
- # User closed the preview window
- return ""
- for r in proc.results:
- if str(r.type) != 'QRCODE':
- continue
- # hiding the preview window stops the camera
- proc.visible = False
- return r.data
+def scan_barcode(device='', timeout=-1, display=True, threaded=False):
+ if libzbar is None:
+ raise RuntimeError("Cannot start QR scanner; zbar not available.")
+ libzbar.zbar_symbol_get_data.restype = c_char_p
+ proc = libzbar.zbar_processor_create(threaded)
+ libzbar.zbar_processor_request_size(proc, 640, 480)
+ libzbar.zbar_processor_init(proc, device, display)
+ libzbar.zbar_processor_set_visible(proc)
+ if libzbar.zbar_process_one(proc, timeout):
+ symbols = libzbar.zbar_processor_get_results(proc)
+ else:
+ symbols = None
+ libzbar.zbar_processor_destroy(proc)
+ if symbols is None:
+ return
+ if not libzbar.zbar_symbol_set_get_size(symbols):
+ return
+ symbol = libzbar.zbar_symbol_set_first_symbol(symbols)
+ data = libzbar.zbar_symbol_get_data(symbol)
+ return data
def _find_system_cameras():
device_root = "/sys/class/video4linux"
@@ -71,3 +70,7 @@ def _find_system_cameras():
name = name.strip('\n')
devices[name] = os.path.join("/dev",device)
return devices
+
+
+if __name__ == "__main__":
+ print(scan_barcode())
diff --git a/lib/simple_config.py b/lib/simple_config.py
@@ -232,6 +232,13 @@ class SimpleConfig(PrintError):
fee_rate = self.get('fee_per_kb', self.max_fee_rate()/2)
return fee_rate
+ def get_video_device(self):
+ device = self.get("video_device", "default")
+ if device == 'default':
+ device = ''
+ return device
+
+
def read_system_config(path=SYSTEM_CONFIG_PATH):
"""Parse and return the system config settings in /etc/electrum.conf."""
result = {}