zoukankan      html  css  js  c++  java
  • pyqt5入门练习-扫描条形码(二)

    六、扫描事件

    打开barcode.ui 双击第二个表格 依次写出各个字段



    # main.py
    from PyQt5 import QtCore, QtGui
    import barcode
    import sys
    import time
    import os
    from PyQt5.QtWidgets import QApplication, QMainWindow, QFileDialog, QMessageBox, QTableWidgetItem
    # 文件集合, 保存选择的文件的绝对路径, 确保元素不重复
    fileSet = set()
    
    # method
    def importEvent(mw, ui):
        files = QFileDialog.getOpenFileNames(mw, '打开文件', './', ("Images (*.png *.jpg *.bmp *.gif *.raw *.tif *.xpm)"))
        if !files:
            return
        for i in files[0]:
            fileSet.add(i)
        ui.totalFile.setText(str(len(fileSet)))  # 文件总数
        ui.fileList.clearContents()
        ui.fileList.setRowCount(0)
        for file in fileSet:
            row = ui.fileList.rowCount()
            ui.fileList.insertRow(row)
            # 文件名
            fileNameItem = QTableWidgetItem(os.path.basename(file))
            fileNameItem.setTextAlignment(QtCore.Qt.AlignCenter)
            # 文件大小
            fileSizeItem = QTableWidgetItem(str("%.2f" % (os.path.getsize(file) / 1024)) + "KB")
            fileSizeItem.setTextAlignment(QtCore.Qt.AlignCenter)
            # 文件绝对路径
            filePathItem = QTableWidgetItem(file)
            filePathItem.setTextAlignment(QtCore.Qt.AlignCenter)
            # 文件创建时间
            createTimeItem = QTableWidgetItem(timeToStrTime(os.path.getctime(file)))
            createTimeItem.setTextAlignment(QtCore.Qt.AlignCenter)
            # 文件修改时间
            modifyTimeItem = QTableWidgetItem(timeToStrTime(os.path.getmtime(file)))
            modifyTimeItem.setTextAlignment(QtCore.Qt.AlignCenter)
            ui.fileList.setItem(row, 0, fileNameItem)
            ui.fileList.setItem(row, 1, fileSizeItem)
            ui.fileList.setItem(row, 2, filePathItem)
            ui.fileList.setItem(row, 3, createTimeItem)
            ui.fileList.setItem(row, 4, modifyTimeItem)
    
    def timeToStrTime(timestamp):
        """将时间戳转化为格式时间字符串"""
        timeStruct = time.localtime(timestamp)
        return time.strftime('%Y-%m-%d %H:%M', timeStruct)
    
    def startScan(mw, ui):
        if len(fileSet) == 0:
            QMessageBox.information(mw, '提示', '你没有选择任何条形码图片文件!', QMessageBox.Ok, QMessageBox.Ok)
            return
        successCount = 0  # 成功检测数
        failCount = 0  # 失败检测数
        cmd = ".\ZBar\bin\zbarimg.exe " 
        ui.resultList.clearContents()
        ui.resultList.setRowCount(0)
        for file in fileSet:
            array = execCmd(cmd + file) # 执行命令.zbarimg.exe imgPath
            row = ui.resultList.rowCount()
            ui.resultList.insertRow(row)
            fileNameItem = QTableWidgetItem(os.path.basename(file))
            fileNameItem.setTextAlignment(QtCore.Qt.AlignCenter)
            if len(array) == 0:
                # 设置失败红色字体
                statusItem = QTableWidgetItem("扫描失败")
                statusItem.setTextAlignment(QtCore.Qt.AlignCenter)
                brush = QtGui.QBrush(QtGui.QColor(234, 31, 42))
                brush.setStyle(QtCore.Qt.NoBrush)
                statusItem.setForeground(brush)
    
                typeItem = QTableWidgetItem("请调整图片清晰度")
                typeItem.setTextAlignment(QtCore.Qt.AlignCenter)
                brush = QtGui.QBrush(QtGui.QColor(234, 31, 42))
                brush.setStyle(QtCore.Qt.NoBrush)
                typeItem.setForeground(brush)
    
                valueItem = QTableWidgetItem("请调整图片清晰度")
                valueItem.setTextAlignment(QtCore.Qt.AlignCenter)
                brush = QtGui.QBrush(QtGui.QColor(234, 31, 42))
                brush.setStyle(QtCore.Qt.NoBrush)
                valueItem.setForeground(brush)
                failCount += 1
            else:
                # 设置成功绿色字体
                statusItem = QTableWidgetItem("扫描成功")
                statusItem.setTextAlignment(QtCore.Qt.AlignCenter)
                brush = QtGui.QBrush(QtGui.QColor(35, 177, 32))
                brush.setStyle(QtCore.Qt.NoBrush)
                statusItem.setForeground(brush)
    
                result = array[0].split(":") # 分离字符串得到条形码格式和内容
                codebarType = result[0]  # 条形码格式
                codebarValue = result[1].strip() # 条形码内容, 去掉两端的空格、制表符trim()函数
                typeItem = QTableWidgetItem(codebarType)
                typeItem.setTextAlignment(QtCore.Qt.AlignCenter)
    
                valueItem = QTableWidgetItem(codebarValue)
                valueItem.setTextAlignment(QtCore.Qt.AlignCenter)
                successCount += 1
            ui.resultList.setItem(row, 0, fileNameItem)
            ui.resultList.setItem(row, 1, statusItem)
            ui.resultList.setItem(row, 2, typeItem)
            ui.resultList.setItem(row, 3, valueItem)
            ui.successScanNum.setText(str(successCount)) # 设置成功扫描的文件数
            ui.failScanNum.setText(str(failCount))
    
    def exitEvent(mw):
        """退出事件"""
        mw.close()
    
    def execCmd(cmd):
        """执行控制台命令"""
        result = os.popen(cmd)
        text = result.readlines()
        result.close()
        return text
    
    if __name__ == "__main__":
        app = QApplication(sys.argv)
        mw = QMainWindow()
        ui = barcode.Ui_MainWindow()
        ui.setupUi(mw)
        mw.show()
        # 主体代码
    
        # 字段显示宽度
        ui.fileList.setColumnWidth(0, 150)
        ui.fileList.setColumnWidth(1, 150)
        ui.fileList.setColumnWidth(2, 500)
        ui.fileList.setColumnWidth(3, 200)
        ui.fileList.setColumnWidth(4, 200)
        ui.resultList.setColumnWidth(0, 150)
        ui.resultList.setColumnWidth(1, 150)
        ui.resultList.setColumnWidth(2, 400)
        ui.resultList.setColumnWidth(3, 400)
    
        # 按钮
        ui.scanBtn.clicked.connect(lambda: startScan(mw, ui))  # 扫描按钮
        ui.importBtn.clicked.connect(lambda: importEvent(mw, ui))  # 导入按钮
        ui.exitBtn.clicked.connect(lambda: exitEvent(mw))  # 退出按钮
        sys.exit(app.exec_())
    

    通过execCmd()方法执行控制台指令, cmd = ".\ZBar\bin\zbarimg.exe "即执行main.py运行的当前目路下的ZBar/bin/zbarimg.exe程序, 只要后面追加一个图片的绝对路径就可以实现扫描操作, 要注意的是zbarimg.exe与图片绝对路径之间有个空格。execCmd()通过执行命令得到结果, 通过把结果加载到内存中, 然后再分离各个字符串, 得到扫描结果return的text是一个列表, 里面要么只有1个元素就是扫描结果, 要么就没有元素未扫描出结果, 很简单的就可以判定
    运行main.py

    七、导出到excel

    使用xlwt模块pip install xlwt

    # main.py
    def exportEvent(mw, ui):
        """保存到excel"""
        if len(fileSet) == 0:
            QMessageBox.information(mw, '提示', '你没有选择任何条形码图片文件!', QMessageBox.Ok, QMessageBox.Ok)
            return
        # 创建一个workbook 设置编码
        workbook = xlwt.Workbook(encoding='utf-8')
        # 创建一个worksheet
        worksheet = workbook.add_sheet('sheet1')
        # 样式
        t = xlwt.Font()
        t.colour_index = 10  # 红色字体
        redColorFont = xlwt.XFStyle()
        redColorFont.font = t
    
        t = xlwt.Font()
        t.colour_index = 57  # 绿色字体
        greenColorFont = xlwt.XFStyle()
        greenColorFont.font = t
    
        # 参数对应 行, 列, 值
        worksheet.write(0, 0, label='文件名')
        worksheet.col(0).width = 256 * 20
        worksheet.write(0, 1, label='扫描状态')
        worksheet.write(0, 2, label='格式')
        worksheet.write(0, 3, label='值')
        worksheet.col(3).width = 256 * 20
        worksheet.write(0, 4, label='文件路径')
        worksheet.col(4).width = 256 * 80
    
        cmd = ".\ZBar\bin\zbarimg.exe "
        row = 1
        for file in fileSet:
            worksheet.write(row, 0, label=os.path.basename(file))
            array = execCmd(cmd + file)
            if len(array) == 0:
                worksheet.write(row, 1, u'扫描失败', redColorFont)
            else:
                worksheet.write(row, 1, u'扫描成功', greenColorFont)
                result = array[0].split(":")
                worksheet.write(row, 2, label=result[0])
                worksheet.write(row, 3, label=result[1].strip())
            worksheet.write(row, 4, label=file)
            row += 1
        # 保存
        workbook.save('.\data.xls')
    

    八、pyinstaller打包

    使用pyinstaller把.py文件打包成.exe文件, 其中有很多坑, 比如图片资源没法打包, 路径问题等
    进入main.py文件所在目录
    由于没法直接打包图片, 所以需要将图片解码成.py文件然后再当成模块在python中使用
    准备一个图标图标
    先在qt designer中设置windowIcon

    然后保存, 使用pyUIC转化一下barcode.ui文件
    窗口的图标就设置好了
    打包图片资源:

    1. 创建resource.qrc文件
    2. 输入以下内容(要保证图片和.qrc文件在同一目录)
    <RCC>
      <qresource prefix="/" >
        <file>favicon.png</file>
      </qresource>
    </RCC>
    
    1. pyrcc5 -o resource.py resource.qrc转换得到resource.py模块
    2. 在barcode.py文件中引入resource.py模块
    3. 修改用到的图片路径, 在前面加引号:

    即使pycharm提示没使用也没关系, 打包后可以自动引用,虽然pycharm运行的时候窗口没有显示图标,但打包后就可以看到
    将favicon.png复制一份, 改后缀为ico文件
    打包:
    pyinstaller -w main.py -i favicon.ico -n "barcodeKing"
    -w窗口运行伴随控制台, 方便调试
    -i参数是设置.exe文件的图标
    -F参数, 把文件打包成单个.exe文件, 不推荐, 因为ZBar是外部程序, 不能被打包进.exe, 会造成路径问题闪退
    -n为.exe文件命名



    打包成功
    进入dist->barcodeKing, 把ZBar目录复制到与barcodeKing.exe同级的目录下



    运行良好

    九、小结

    没有很深入的研究, 只是pyqt5入门的操作, 写得不清楚也请见谅, 我是很水的
    源码在这里https://github.com/CaseyFu/python/tree/master/src/GUI/barcode
    如果你也是为了完成任务可以交我这个/doge哈哈哈哈

    ←pyqt5入门练习-扫描条形码(一)

  • 相关阅读:
    spring cloud网关gateway
    maven将依赖第三方包打包(package)到jar中
    spring boot创建多模块聚合工程
    spring cloud服务间调用feign
    取模和取余的区别
    实现多线程编程的三种方式
    打开eclipse编译后的.class文件
    对中断interrupt的理解
    对final和static的理解
    对synchronized的一点理解
  • 原文地址:https://www.cnblogs.com/xfk1999/p/python-pyqt5-barcode-two.html
Copyright © 2011-2022 走看看