pyqt5入門練習-掃描條形碼(一)


問題

使用pyqt5, Qt Designer, PyUIC, pycharm, ZBar練習python GUI開發, 掃描條形碼案例
最近學習做python GUI開發, 為了完成老師布置的任務, 做一個配合ZBar掃描條形碼的小程序, 不打算過多深究二維碼什么的
我能找到的教程就是http://code.py40.com/pyqt5/這個網站, 但是這個教材沒有使用qt designer, 前期給了我很大的困惑
先上一張圖, 看看效果


圖1 成品

簡單得不能再簡單了, 但第一次寫有點磕磕絆絆的

  • 工具:pycharm + qt Designer + pyUIC + ZBar
  • qt Designer的主要功能就是把圖形界面做出來
  • pyUIC的主要功能就是把圖形界面翻譯成.py文件
  • ZBar的功能是掃描圖片上的條形碼

主要實現的功能有: 用外部程序ZBar掃描圖片、用xlwt庫導出數據到excel, pyinstaller打包python文件, 其它的就是pyqt5的一些操作比如選擇文件、換ico圖標之類的

工具的安裝

安裝pyqt5 pip install pyqt5
安裝pyqt5-tools pip install pyqt5-tools
完成了之后qt designer就安裝在你的python根目錄下的\Lib\site-packages\pyqt5_tools\Qt\bin\下
配置pycharm File->settings->Tools->External Tools->+


配置qt designer


圖2 配置qt designer

配置pyUIC


圖3 配置pyUIC

參數:-m PyQt5.uic.pyuic $FileName$ -o $FileNameWithoutExtension$.py


工具的位置:


圖4 工具的位置

安裝ZBar
https://sourceforge.net/projects/zbar/files/zbar/0.10/zbar-0.10-setup.exe/download
安裝到你項目的目錄中, 進入ZBar/bin/目錄, 在此處打開控制台, 准備一張條形碼圖片(ZBar/example目錄中有一張條形碼)
執行命令zbarimg.exe ../examples/barcode.png


圖5 執行命令

掃描出來就證明成功了, bin/下的另一個zbarcam.exe是用來掃視頻中的條形碼的

運行第一個Helloworld

pycharm new一個python項目出來
Tools->External Tools->Qt Designer
創建一個Main Window模板(我第一次創建了個對話框, 怎么也運行不了, 血的代價)
左邊工具欄Display Widgets拖一個Label到窗口中間, 安靜地敲下Helloworld


圖6

右擊HelloWorld->change styleSheet


圖7

這是你熟悉的css, 我們看到字有點超出邊界了, 這里有個小技巧
右擊Helloword->Layout->Adjust Size
這時候Helloworld飽滿了
Ctrl+S保存到項目文件夾
左鍵選中helloworld.ui(一定要選中) 尋找工具pyUIC 點擊 自動生成了helloworld.py文件
在項目目錄中新建main.py文件作為主入口, 與圖形界面的代碼分離(試過就知道很方便), 並敲下如下代碼:

import sys
from PyQt5.QtWidgets import QApplication, QMainWindow
import helloworld

if __name__ == "__main__":
    app = QApplication(sys.argv)
    mw = QMainWindow()
    ui = helloworld.Ui_MainWindow()
    ui.setupUi(mw)
    mw.show()
    # 邏輯代碼
    
    sys.exit(app.exec_())

運行main.py


圖8

界面制作

Tools->External Tools->Qt Desginer
創建一個Main Window 先把界面擺好
Buttons->Push Button拖出兩個按鈕
Item Widgets->Table Widget拖出兩個表格框
Display Widgets->Label拖出標簽


圖9

文件數:0是兩個不同標簽
接下來開始為每個組件命名, 要做到見名知意
選中導入按鈕命名為importBtn


圖10

依次地


圖10

保存到項目目錄為barcode.ui->左鍵點擊選中->Tools->External Tools->pyUIC
得到barcode.py 圖形界面的代碼

觸發按鈕

首先在main.py文件中進口barcode.py模塊, 更改barcode模塊生成ui對象
有兩個對象ui對象和MainWindow對象
通過ui對象可以管理按鈕、標簽等組件, 通過MainWindow可以進行關閉窗口等操作
通過點擊按鈕 觸發事件
先寫最簡單的退出按鈕

# main.py
import sys
from PyQt5.QtWidgets import QApplication, QMainWindow
import barcode

def exitEvent(mw):
    mw.close()

if __name__ == "__main__":
    app = QApplication(sys.argv)
    mw = QMainWindow()
    ui = barcode.Ui_MainWindow()
    ui.setupUi(mw)
    mw.show()
    # 邏輯代碼
    ui.exitBtn.clicked.connect(lambda: exitEvent(mw))
    sys.exit(app.exec_())

ui.exitBtn.clicked.connect(lambda: exitEvent(mw))這里使用lambda表達式主要是為了解決傳參問題,還有一種partial傳參方式沒lambda好用。把mw主窗口對象傳遞到exitEvent()函數中, 對mw對象進行操作, 實現操作的模塊化, 比如加個退出的確認框呀什么的
運行main.py 點擊退出按鈕 退出界面

選擇文件

打開barcode.ui 雙擊第一個表格框 寫出各個字段




圖組11

然后點擊保存, 直接用pyUIC轉換成barcode.py文件, 這就是分離的好處, 只管界面, 不管邏輯。
我們可以通過觀察barcode.py學習這個表格是怎么注入數據的, 如這一段

# def setupUi()
item = QtWidgets.QTableWidgetItem()
self.fileList.setItem(0, 0, item)
# 在(0,0)位置處生成一個單元格
# def retranslateUi()
item = self.fileList.item(0, 0)
item.setText(_translate("MainWindow", "1"))
# 在(0,0)處注入1這個字符

可以看到setupUi()方法專注於創建, 而retranslateUi()方法專注於注入數據, 就像蓋樓一樣, 我們先把框架搭好, 然后再在里面添磚加瓦

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)"))
    for i in files[0]:
        fileSet.add(i)
    ui.totalFileNum.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(timeStampToStrTime(os.path.getctime(file)))
        createTimeItem.setTextAlignment(QtCore.Qt.AlignCenter)
        # 文件修改時間
        modifyTimeItem = QTableWidgetItem(timeStampToStrTime(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 exitEvent(mw):
    """退出事件"""
    mw.close()

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.importBtn.clicked.connect(lambda: importEvent(mw, ui))  # 導入按鈕
    ui.exitBtn.clicked.connect(lambda: exitEvent(mw))  # 退出按鈕
    sys.exit(app.exec_())
  • 這里用到文件選擇器, 要用QFileDialog.getOpenFileNames(), 按住Ctrl可以選擇多個文件。 別用getOpenfileName()這個一次只能選擇一個文件。

  • 返回的files是一個元組, ([文件1絕對路徑, 文件2絕對路徑, ...], 文件類型)
    files[0]返回的是選中的文件的絕對路徑, 有了絕對路徑就好辦事了, 文件名、大小、創建時間等屬性可以由os.path得到

  • 創建一個集合fileSet用於保存文件的絕對路徑, 這樣就不怕選擇了重復的文件

  • ("Images (*.png *.jpg *.bmp *.gif *.raw *.tif *.xpm)")是對文件類型的限制, 去掉這個參數就是可以添加任何文件
    每次新加入文件就把原來的表格內容清空同時行號置0

ui.fileList.clearContents()
ui.fileList.setRowCount(0)

運行main.py


圖12

pyqt5入門練習-掃描條形碼(二)


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM