qt: new qrreader using QtMultimedia; drop CalinsQRReader(mac)
This commit ports the work of EchterAgo and cculianu from Electron-Cash, to implement a new toolchain to scan qr codes. Previously, on Linux and Win, we have been using zbar to access the camera and read qrcodes; and on macOS we used CalinsQRReader (an objective-C project by cculianu). The new toolchain added here can use QtMultimedia to access the camera, and then feed that image into zbar. When used this way, zbar needs fewer dependencies and is easier to compile, in particular it can be compiled for macOS. The new toolchain works on all three platforms, with some caveats (see code comments in related commits) -- so we also keep the end-to-end zbar toolchain; but at least we can drop CalinsQRReader. The related changes in Electron-Cash are spread over 50+ commits (several PRs and direct pushes to master), but see in particular: https://github.com/Electron-Cash/Electron-Cash/pull/1376 some other interesting links:b2b737001c163224cf1f3b31e0fcb1eda015908ehttps://github.com/Electron-Cash/Electron-Cash/pull/1545052aa06c23
This commit is contained in:
@@ -72,24 +72,49 @@ class ScanQRTextEdit(ButtonsTextEdit, MessageBoxMixin, Logger):
|
||||
else:
|
||||
self.setText(data)
|
||||
|
||||
def qr_input(self):
|
||||
from electrum import qrscanner
|
||||
data = ''
|
||||
# Due to the asynchronous nature of the qr reader we need to keep the
|
||||
# dialog instance as member variable to prevent reentrancy/multiple ones
|
||||
# from being presented at once.
|
||||
qr_dialog = None
|
||||
|
||||
def qr_input(self, *, callback=None) -> None:
|
||||
if self.qr_dialog:
|
||||
self.logger.warning("QR dialog is already presented, ignoring.")
|
||||
return
|
||||
from . import ElectrumGui
|
||||
if ElectrumGui.warn_if_cant_import_qrreader(self):
|
||||
return
|
||||
from .qrreader import QrReaderCameraDialog, CameraError, MissingQrDetectionLib
|
||||
try:
|
||||
data = qrscanner.scan_barcode(self.config.get_video_device())
|
||||
except UserFacingException as e:
|
||||
self.show_error(e)
|
||||
except BaseException as e:
|
||||
self.qr_dialog = QrReaderCameraDialog(parent=self.top_level_window(), config=self.config)
|
||||
|
||||
def _on_qr_reader_finished(success: bool, error: str, data):
|
||||
if self.qr_dialog:
|
||||
self.qr_dialog.deleteLater()
|
||||
self.qr_dialog = None
|
||||
if not success:
|
||||
if error:
|
||||
self.show_error(error)
|
||||
return
|
||||
if not data:
|
||||
data = ''
|
||||
if self.allow_multi:
|
||||
new_text = self.text() + data + '\n'
|
||||
else:
|
||||
new_text = data
|
||||
self.setText(new_text)
|
||||
if callback and success:
|
||||
callback(data)
|
||||
|
||||
self.qr_dialog.qr_finished.connect(_on_qr_reader_finished)
|
||||
self.qr_dialog.start_scan(self.config.get_video_device())
|
||||
except (MissingQrDetectionLib, CameraError) as e:
|
||||
self.qr_dialog = None
|
||||
self.show_error(str(e))
|
||||
except Exception as e:
|
||||
self.logger.exception('camera error')
|
||||
self.qr_dialog = None
|
||||
self.show_error(repr(e))
|
||||
if not data:
|
||||
data = ''
|
||||
if self.allow_multi:
|
||||
new_text = self.text() + data + '\n'
|
||||
else:
|
||||
new_text = data
|
||||
self.setText(new_text)
|
||||
return data
|
||||
|
||||
def contextMenuEvent(self, e):
|
||||
m = self.createStandardContextMenu()
|
||||
|
||||
Reference in New Issue
Block a user