翻译|使用教程|编辑:杨鹏连|2021-03-04 16:14:06.970|阅读 356 次
概述:Qt Designer是用于使用Qt小部件构建跨平台图形用户界面(GUI)的Qt工具。在本文中,我将使用Qt设计器通过适用于Windows,Linux,macOS和Raspberry Pi OS的Dynamsoft Python条形码SDK创建高级桌面条形码读取器应用程序。该应用程序包含Dynamsoft条码阅读器的所有强大功能。
# 慧都年终大促·界面/图表报表/文档/IDE等千款热门软控件火热促销中 >>
Dynamsoft Barcode Reader SDK一款多功能的条码读取控件,只需要几行代码就可以将条码读取功能嵌入到Web或桌面应用程序。这可以节省数月的开发时间和成本。能支持多种图像文件格式以及从摄像机或扫描仪获取的DIB格式。使用Dynamsoft Barcode Reader SDK,你可以创建强大且实用的条形码扫描仪软件,以满足你的业务需求。
点击下载Dynamsoft Barcode Reader最新版
Qt Designer是用于使用Qt小部件构建跨平台图形用户界面(GUI)的Qt工具。在本文中,我将使用Qt设计器通过适用于Windows,Linux,macOS和Raspberry Pi OS的Dynamsoft Python条形码SDK创建高级桌面条形码读取器应用程序。该应用程序包含Dynamsoft条码阅读器的所有强大功能。
使用Qt Designer构造UI
所需的Qt小部件包括:
菜单栏
pyside2-uic design.ui -o design.py用Python构建跨平台条形码阅读器
让我们逐步构建条形码阅读器应用程序。
要求
安装相关的Python软件包。对于Raspberry Pi OS,我们可以通过以下apt-get命令安装PySide2 :
python3 -m pip install opencv-python python3 -m pip install dbr # Windows, Linux and macOS python3 -m pip install PySide2 # Raspberry Pi OS sudo apt-get install python3-pyside2.qt3dcore python3-pyside2.qt3dinput python3-pyside2.qt3dlogic python3-pyside2.qt3drender python3-pyside2.qtcharts python3-pyside2.qtconcurrent python3-pyside2.qtcore python3-pyside2.qtgui python3-pyside2.qthelp python3-pyside2.qtlocation python3-pyside2.qtmultimedia python3-pyside2.qtmultimediawidgets python3-pyside2.qtnetwork python3-pyside2.qtopengl python3-pyside2.qtpositioning python3-pyside2.qtprintsupport python3-pyside2.qtqml python3-pyside2.qtquick python3-pyside2.qtquickwidgets python3-pyside2.qtscript python3-pyside2.qtscripttools python3-pyside2.qtsensors python3-pyside2.qtsql python3-pyside2.qtsvg python3-pyside2.qttest python3-pyside2.qttexttospeech python3-pyside2.qtuitools python3-pyside2.qtwebchannel python3-pyside2.qtwebsockets python3-pyside2.qtwidgets python3-pyside2.qtx11extras python3-pyside2.qtxml python3-pyside2.qtxmlpatterns python3-pyside2uic加载UI文件
因为UI代码已经准备好,所以我们可以按以下方式加载它:
''' Usage: app.py <license.txt> ''' import sys from PySide2.QtGui import QPixmap, QImage from PySide2.QtWidgets import QApplication, QMainWindow, QInputDialog from PySide2.QtCore import QFile, QTimer from PySide2.QtWidgets import * from design import Ui_MainWindow from barcode_manager import * import os import cv2 from dbr import EnumBarcodeFormat, EnumBarcodeFormat_2 class MainWindow(QMainWindow): def __init__(self, license): super(MainWindow, self).__init__() self.ui = Ui_MainWindow() self.ui.setupUi(self) def main(): try: with open(sys.argv[1]) as f: license = f.read() except: license = "" app = QApplication(sys.argv) window = MainWindow(license) window.show() sys.exit(app.exec_()) if __name__ == '__main__': print(__doc__) main()我们可以使用有效的条形码许可证密钥启动应用程序,也可以稍后通过菜单栏激活SDK。
下一步是创建一些全局变量并将小部件信号绑定到插槽:
# Initialization self._all_data = {} self._results = None # Dynamsoft Barcode Reader self._barcodeManager = BarcodeManager(license) # Create a timer. self.timer = None # Open camera self._cap = None # self.openCamera() # Resolution list self.ui.comboBox.currentTextChanged.connect(self.onComboBoxChanged) # The current path. self._path = os.path.dirname(os.path.realpath(__file__)) # Camera button self.ui.pushButton_open.clicked.connect(self.openCamera) self.ui.pushButton_stop.clicked.connect(self.stopCamera) # Load file self.ui.actionOpen_File.triggered.connect(self.openFile) # Load directory self.ui.actionOpen_Folder.triggered.connect(self.openFolder) # Export template self.ui.actionExport_template.triggered.connect(self.exportTemplate) # About self.ui.actionAbout.triggered.connect(self.about) # Set license self.ui.actionEnter_License_Key.triggered.connect(self.setLicense) ## List widget self.ui.listWidget.currentItemChanged.connect(self.currentItemChanged) ## Template load button self.ui.pushButton_template.clicked.connect(self.loadTemplate) ## Template export button self.ui.pushButton_export_template.clicked.connect(self.exportTemplate)用于打开和保存文件的文件对话框
基本的文件操作包括加载图像文件,从文件夹加载一批图像文件,加载和保存模板文件。
def openFile(self): filename = QFileDialog.getOpenFileName(self, 'Open File', self._path, "Barcode images (*)") if filename is None or filename[0] == '': return filename = filename[0]
def openFolder(self): dir = QFileDialog.getExistingDirectory(self, 'Open Folder', self._path, QFileDialog.ShowDirsOnly) if dir is '': return files = [os.path.join(dir, f) for f in os.listdir(dir) if os.path.isfile(os.path.join(dir, f))] if len(files) == 0: return for filename in files: self.appendFile(filename)
def exportTemplate(self): filename = QFileDialog.getSaveFileName(self, 'Save File', self._path, "Barcode Template (*.json)") if filename is None or filename[0] == '': return filename = filename[0]解码JPEG,PNG,TIFF,PDF和GIF文件中的条形码
如果您更喜欢OpenCV API,则可以像下面这样解码条形码:
frame = cv2.imread(filename) results = self._reader.decode_buffer(frame)但是,OpenCV仅支持JPEG,PNG和TIFF。Dynamsoft Python条形码SDK提供的图像编解码器还支持PDF和GIF文件。要涵盖更多图像格式,我们可以致电decode_file():
results = self._reader.decode_file(filename)别忘了我们需要在标签窗口小部件中显示图像。因此,还有一个步骤是从中间结果中获取图像数据,然后将其转换为NumPy数组:
intermediate_results = self._reader.get_all_intermediate_results() imageData = intermediate_results[0].results[0] buffer = imageData.bytes width = imageData.width height = imageData.height stride = imageData.stride format = imageData.image_pixel_format channel = 3 if format == EnumImagePixelFormat.IPF_RGB_888: channel = 3 elif format == EnumImagePixelFormat.IPF_BINARY or format == EnumImagePixelFormat.IPF_GRAYSCALED or format == EnumImagePixelFormat.IPF_BINARYINVERTED: channel = 1 if format == EnumImagePixelFormat.IPF_BINARY or format == EnumImagePixelFormat.IPF_BINARYINVERTED: whiteValue = 1 if format == EnumImagePixelFormat.IPF_BINARYINVERTED: whiteValue = 0 binData = bytearray(len(buffer) << 3) count = 0 for pos in range(len(buffer)): for bit in range(7, -1, -1): if (buffer[pos] >> bit) & 0x01 == whiteValue: binData[count] = 255 else: binData[count] = 0 count += 1 frame = np.ndarray((height, width, channel), np.uint8, binData, 0, (stride << 3, channel, 1)) else: frame = np.ndarray((height, width, channel), np.uint8, buffer, 0, (stride, channel, 1))显示网络摄像头流
我们触发一个计时器来显示网络摄像头流:
def openCamera(self): width = 640; height = 480 self._cap = cv2.VideoCapture(0) self._cap.set(cv2.CAP_PROP_FRAME_WIDTH, width) self._cap.set(cv2.CAP_PROP_FRAME_HEIGHT, height) if not self._cap.isOpened(): self.showMessageBox('Error', "Failed to open camera.") return self.timer = QTimer() self.timer.timeout.connect(self.nextFrameUpdate) self.timer.start(1000./24) def nextFrameUpdate(self): ret, frame = self._cap.read() frame, self._results = self._barcodeManager.decode_frame(frame) self.showResults(frame, self._results)创建用于实时条形码扫描的Python流程
解码条形码是一项占用大量CPU的任务。为了避免实时阻塞UI,我们创建了一个Python进程来运行代码:
def create_barcode_process(self): size = 1 self.frameQueue = Queue(size) self.resultQueue = Queue(size) self.barcodeScanning = Process(target=process_barcode_frame, args=(self._license, self.frameQueue, self.resultQueue, self._template, self._types, self._types2)) self.barcodeScanning.start()运行GUI条形码阅读器
python3 app_advanced.py license.txt视窗
本站文章除注明转载外,均为本站原创或翻译。欢迎任何形式的转载,但请务必注明出处、不得修改原文相关链接,如果存在内容上的异议请邮件反馈至chenjj@pclwef.cn
文章转载自: