pyqt5學習記錄

来源:https://www.cnblogs.com/xfk1999/archive/2020/05/19/12913205.html
-Advertisement-
Play Games

一、寫在開頭 無聊寫寫。最近學習做python GUI, 感覺比網頁落後好多。我只是為了完成老師佈置的任務, 做一個配合ZBar掃描條形碼的小程式, 不打算過多深究二維碼什麼的。由於pyqt5貌似不是很火爆, 沒多少成系統的教程。我能找到的就是 "http://code.py40.com/pyqt5 ...


一、寫在開頭

無聊寫寫。最近學習做python GUI, 感覺比網頁落後好多。我只是為了完成老師佈置的任務, 做一個配合ZBar掃描條形碼的小程式, 不打算過多深究二維碼什麼的。由於pyqt5貌似不是很火爆, 沒多少成系統的教程。我能找到的就是http://code.py40.com/pyqt5/這個網站。不用挨著挨著看, 滑到最下麵show you the code
先上一張圖, 看看效果

簡單得不能再簡單了, 但第一次寫有點磕磕絆絆的
工具:pycharm + qt Designer + pyUIC
qt Designer的主要功能就是把圖形界面做出來
pyUIC的主要功能就是把圖形界面翻譯成.py文件
主要實現的功能有: 用外部程式ZBar掃描圖片、用xlwt庫導出數據到excel, 其它的就是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

配置pyUIC

參數:-m PyQt5.uic.pyuic $FileName$ -o $FileNameWithoutExtension$.py
工具的位置:

至此工具已經安裝好

三、運行第一個Helloword(熱身)

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

右擊HelloWorld->change styleSheet

這應該是你熟悉的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

四、安裝ZBar

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

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

五、界面

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

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

依次地

保存到項目目錄為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傳參方式瞭解就行了。把mw主視窗對象傳遞到exitEvent()函數中, 對mw對象進行操作, 實現操作的模塊化, 比如加個退出的確認框呀什麼的
運行main.py 點擊退出按鈕 退出界面

七、選擇文件

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



然後點擊保存, 直接用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)

其它沒啥好說的, 一些pyqt組件基本屬性操作
運行main.py

八、掃描事件

打開barcode.ui 雙擊第二個表格 依次寫出各個欄位


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')
# main.py
from PyQt5 import QtCore, QtGui
import barcode
import sys
import time
import xlwt
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 not files[0]:
        return
    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(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 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')


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.exportBtn.clicked.connect(lambda: exportEvent(mw, ui))  # 導出按鈕
    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_())

run main.py

運行良好
以上即是在學習pythonGUI上的記錄, 說實話真的沒啥必要, Django不香嗎 vue不香嗎
源碼在這裡https://github.com/CaseyFu/python/tree/master/src/GUI/barcode


您的分享是我們最大的動力!

-Advertisement-
Play Games
更多相關文章
  • # 3.border和background - border-radius border-radius:上左 上右 下右 下左 border-radius:上左下右 上右下左 border-radius:上左 上右下左 下右 border-top-left-radius:10px 10px; bor ...
  • 常用 "CSS選擇器" 查看地址 (https://www.cnblogs.com/hleisurely/p/12836777.html) 1.選擇器的優先順序 !important的優先順序別最高 權重值為1111 用來提升某個直接選中標簽的選擇器中某個屬性的優先順序的,可以將被指定的屬性的優先順序提升為 ...
  • 前言 Deno 已經正式發佈了! 我說這句話時候,是不是很多前端 和 NodeJS 工(碼)程(農)師已經按不住自己的40米大刀了。心中的不僅感慨前端是真的會造輪子,有了 node 還不夠嗎,還沒學會 node 又搞了個 deno,node 和 deno 啥區別?! 的確,deno 和 node 形 ...
  • 今天給大家整理出來了web前端工程師初級階段需要掌握的內容,很全面,希望大家好好閱讀,看看自己掌握的知識點和文章裡面寫的還相差多少。 什麼是初級web前端工程師? 初級前端工程師:首先要知道的就是如何處理各種瀏覽器的相容處理(比如說在IE瀏覽器中的createElement有什麼不同等等內容),現在 ...
  • 一、ajax 輪詢實現原理:ajax 輪詢指客戶端每間隔一段時間向服務端發起請求,保持數據的同步。 優點:可實現基礎(指間隔時間較短)的數據更新。 缺點:這種方法也只是儘量的模擬即時傳輸,但並非真正意義上的即時通訊,很有可能出現客戶端請求時,服務端數據並未更新。或者服務端數據已更新,但客戶端未發起請 ...
  • 一、發展由來 POP OOP AOP DDD POP:(面向過程編程) 描述:考慮問題是1234步驟 特點:簡單,無法應對複雜需求 舉例子:把食物放冰箱 第一步:打開冰箱 第二步:塞進去食物 第三步:關冰箱 OOP:面向對象編程 特點:把事物作為對象考慮 特性:封裝、繼承、多態 描述:對象交互,完成 ...
  • 使用CLion替換VSCode,開發 chromium kernel(for Linux) VSCode 不適合開發像chromium 這樣的巨型c++工程,Microsoft的cpptools和mono(.net移植,被VScode用作來寫code intellisense)存在的嚴重的memor ...
  • 1. 單向一對多配置 單向一對多使用@OneToMany標簽進行配置,在一方有一個集合屬性與多方進行關聯,集合可以是List或者Set,區別是List是有序、Set是無序不重覆。 對應在一方配置@OneToMany: /** * 單向一對多:使用JPA配置 */ @Entity @Table(nam ...
一周排行
    -Advertisement-
    Play Games
  • 移動開發(一):使用.NET MAUI開發第一個安卓APP 對於工作多年的C#程式員來說,近來想嘗試開發一款安卓APP,考慮了很久最終選擇使用.NET MAUI這個微軟官方的框架來嘗試體驗開發安卓APP,畢竟是使用Visual Studio開發工具,使用起來也比較的順手,結合微軟官方的教程進行了安卓 ...
  • 前言 QuestPDF 是一個開源 .NET 庫,用於生成 PDF 文檔。使用了C# Fluent API方式可簡化開發、減少錯誤並提高工作效率。利用它可以輕鬆生成 PDF 報告、發票、導出文件等。 項目介紹 QuestPDF 是一個革命性的開源 .NET 庫,它徹底改變了我們生成 PDF 文檔的方 ...
  • 項目地址 項目後端地址: https://github.com/ZyPLJ/ZYTteeHole 項目前端頁面地址: ZyPLJ/TreeHoleVue (github.com) https://github.com/ZyPLJ/TreeHoleVue 目前項目測試訪問地址: http://tree ...
  • 話不多說,直接開乾 一.下載 1.官方鏈接下載: https://www.microsoft.com/zh-cn/sql-server/sql-server-downloads 2.在下載目錄中找到下麵這個小的安裝包 SQL2022-SSEI-Dev.exe,運行開始下載SQL server; 二. ...
  • 前言 隨著物聯網(IoT)技術的迅猛發展,MQTT(消息隊列遙測傳輸)協議憑藉其輕量級和高效性,已成為眾多物聯網應用的首選通信標準。 MQTTnet 作為一個高性能的 .NET 開源庫,為 .NET 平臺上的 MQTT 客戶端與伺服器開發提供了強大的支持。 本文將全面介紹 MQTTnet 的核心功能 ...
  • Serilog支持多種接收器用於日誌存儲,增強器用於添加屬性,LogContext管理動態屬性,支持多種輸出格式包括純文本、JSON及ExpressionTemplate。還提供了自定義格式化選項,適用於不同需求。 ...
  • 目錄簡介獲取 HTML 文檔解析 HTML 文檔測試參考文章 簡介 動態內容網站使用 JavaScript 腳本動態檢索和渲染數據,爬取信息時需要模擬瀏覽器行為,否則獲取到的源碼基本是空的。 本文使用的爬取步驟如下: 使用 Selenium 獲取渲染後的 HTML 文檔 使用 HtmlAgility ...
  • 1.前言 什麼是熱更新 游戲或者軟體更新時,無需重新下載客戶端進行安裝,而是在應用程式啟動的情況下,在內部進行資源或者代碼更新 Unity目前常用熱更新解決方案 HybridCLR,Xlua,ILRuntime等 Unity目前常用資源管理解決方案 AssetBundles,Addressable, ...
  • 本文章主要是在C# ASP.NET Core Web API框架實現向手機發送驗證碼簡訊功能。這裡我選擇是一個互億無線簡訊驗證碼平臺,其實像阿裡雲,騰訊雲上面也可以。 首先我們先去 互億無線 https://www.ihuyi.com/api/sms.html 去註冊一個賬號 註冊完成賬號後,它會送 ...
  • 通過以下方式可以高效,並保證數據同步的可靠性 1.API設計 使用RESTful設計,確保API端點明確,並使用適當的HTTP方法(如POST用於創建,PUT用於更新)。 設計清晰的請求和響應模型,以確保客戶端能夠理解預期格式。 2.數據驗證 在伺服器端進行嚴格的數據驗證,確保接收到的數據符合預期格 ...