PyQt5简单使用——以二维码识别为例

PyQt5的简单使用——以二维码识别为例

一、PyQt5的安装与配置

$ pip install PyQt5
$ pip install PyQt5-tools

使用上述命令进行安装,其中PyQt5-tools会安装Qt DesignerPyuic

使用这两个工具可以在图形化界面编辑UI然后转换成py文件

这是两个非常好用的工具,不是必须,但很好用且很常用

他们的路径分别是:

designer : "Python文件夹/Lib/site-packages/qt5_applications/Qt/bin/designer.exe"

pyuic : Python文件夹/Scripts/pyuic5.exe

直接使用上述两个工具

  • designer就是正常的软件,可以直接打开使用,也可在命令行后面跟上文件名,用该软件打开指定文件

  • 在designer编辑软件的布局等内容后,保存为.ui文件

  • pyuic为命令行工具,使用方式为

    $ pyuic5.exe source_file.ui -o output_file.py
    

    将designer生成的.ui文件转换成.py文件

使用PyCharm开发时,可将上述两个工具添加到PyCharm

PyCharm的设置-->工具-->外部工具,新建添加工具

  • Qt Designer配置

    Name:可以根据喜好自拟,示例定义为Qt Designer
    Program:designer.exe的路径,一般如上
    Arguments:一般不填写,但也可填写$FileName$,这样可以右键ui文件直接打开编辑
    Working directory:$FileDir$
    
  • Pyuic配置

    Name:可以根据喜好自拟,示例定义为Pyuic.
    Program:Pyuic5.exe的路径,一般如上
    Arguments:$FileName$ -o $FileNameWithoutExtension$.py
    Working directory:$FileDir$
    

使用方法:右键文件,在菜单中找到external tool进行选择使用

二、ui的创建与使用

右键项目文件夹,在external tool选择Qt Designer,新建一个ui文件进行编辑,左边是各种组件,可自行编辑好界面UI,然后保存,保存的是一个.ui文件

右键.ui文件,external tool选择Pyuic直接将其转换,同级目录下会生成相同文件名但以.py结尾的文件,这个py文件就是导出的文件

导出文件的大致内容如下:

# Form implementation generated from reading ui file 'window.ui'
#
# Created by: PyQt5 UI code generator 5.15.9
#
# WARNING: Any manual changes made to this file will be lost when pyuic5 is
# run again.  Do not edit this file unless you know what you are doing.


from PyQt5 import QtCore, QtGui, QtWidgets


class Ui_MainWindow(object):
    def setupUi(self, MainWindow):
        MainWindow.setObjectName("MainWindow")
        MainWindow.resize(641, 335)
        self.centralwidget = QtWidgets.QWidget(MainWindow)
        self.centralwidget.setObjectName("centralwidget")
        self.listWidget = QtWidgets.QListWidget(self.centralwidget)
        self.listWidget.setGeometry(QtCore.QRect(30, 90, 581, 201))
        self.listWidget.setObjectName("listWidget")
        ...  # 一堆如上设置组件属性的内容
        MainWindow.setCentralWidget(self.centralwidget)
        self.statusbar = QtWidgets.QStatusBar(MainWindow)
        self.statusbar.setObjectName("statusbar")
        MainWindow.setStatusBar(self.statusbar)

        self.retranslateUi(MainWindow)
        QtCore.QMetaObject.connectSlotsByName(MainWindow)

        ... # designer设计时绑定的信号与槽

    def retranslateUi(self, MainWindow):
        _translate = QtCore.QCoreApplication.translate
        MainWindow.setWindowTitle(_translate("MainWindow", "软件title"))
        self.pushButton.setText(_translate("MainWindow", "组件文本信息"))
        ...  # 组件文本信息

三、继续编辑导出py,添加自定义内容并实例化

要想显示应用,需要实例化窗口并应用ui

最基本需添加格式如下:

if __name__ == '__main__':
    # 必须的app和sys.exit(和tk.mainloop一样)
    app = QtWidgets.QApplication(sys.argv)

    # 将创建的ui实例化,应用起来
    ui = Ui_MainWindow()
    MainWindow = QtWidgets.QMainWindow()  # 注意网上有些是QWidget,看情况使用
    # ui只是框架,需要传入一个QMainWindow对象作为实体来应用该ui
    ui.setupUi(MainWindow)
    # 显示ui(窗口)
    MainWindow.show()

    sys.exit(app.exec_())

绑定自定义回调函数

接着在Ui_MainWindow类中添加自定义方法,以一个button的click信号为例:

def func(self):  # 自定义回调函数
    do something...
self.pushButton.clicked.connect(self.func)  # 将函数与该事件(click)绑定

在PyQt5中,组件之间通过信号与槽进行交互

具体细节不太理解,只是简单使用。

个人认为Qt的各个组件有很多事件(比如click,selected,doubleclick),这些事件发生是就是发出来信号,然后将这个信号与一个回调函数(槽)绑定(connect),从而实现自定义功能。

三、二维码识别案例源码

思路:点击按钮电脑截屏,从截屏中识别二维码,实现电脑端二维码识别

截屏用的是PIL.ImageGrab.grab()

打开网址用的是webbrowser.open()

二维码识别用的是pyzbar第三方模块(pip install pyzbar)

# -*- coding: utf-8 -*-
"""
电脑二维码识别软件,对当前屏幕截屏,识别截屏里面的二维码,并将识别到的信息列出来
可以双击具体链接打开,也可用点击打开全部一次性打开全部
"""
import sys
from PIL import ImageGrab
from pyzbar import pyzbar
import webbrowser

# Form implementation generated from reading ui file 'window.ui'
#
# Created by: PyQt5 UI code generator 5.15.9
#
# WARNING: Any manual changes made to this file will be lost when pyuic5 is
# run again.  Do not edit this file unless you know what you are doing.


from PyQt5 import QtCore, QtGui, QtWidgets


class Ui_MainWindow(object):
    def setupUi(self, MainWindow):
        MainWindow.setObjectName("MainWindow")
        MainWindow.setFixedSize(396, 233)  # 固定窗口大小,本来是resize,修改为这个禁止人为拉动软件size
        MainWindow.setWindowFlags(QtCore.Qt.WindowStaysOnTopHint)  # 窗口始终置顶
        self.centralwidget = QtWidgets.QWidget(MainWindow)
        self.centralwidget.setObjectName("centralwidget")
        self.listWidget = QtWidgets.QListWidget(self.centralwidget)
        self.listWidget.setGeometry(QtCore.QRect(30, 90, 321, 91))
        self.listWidget.setObjectName("listWidget")
        self.pushButton = QtWidgets.QPushButton(self.centralwidget)
        self.pushButton.setGeometry(QtCore.QRect(50, 20, 121, 51))
        self.pushButton.setObjectName("pushButton")
        self.pushButton_2 = QtWidgets.QPushButton(self.centralwidget)
        self.pushButton_2.setGeometry(QtCore.QRect(200, 30, 111, 41))
        self.pushButton_2.setObjectName("pushButton_2")
        MainWindow.setCentralWidget(self.centralwidget)
        self.statusbar = QtWidgets.QStatusBar(MainWindow)
        self.statusbar.setObjectName("statusbar")
        MainWindow.setStatusBar(self.statusbar)

        self.retranslateUi(MainWindow)
        QtCore.QMetaObject.connectSlotsByName(MainWindow)

        # 将相应事件与相应回调函数绑定
        self.pushButton.clicked.connect(self.grab)
        self.pushButton_2.clicked.connect(self.open_url)
        self.listWidget.itemDoubleClicked.connect(self.double_open)

    def retranslateUi(self, MainWindow):
        _translate = QtCore.QCoreApplication.translate
        MainWindow.setWindowTitle(_translate("MainWindow", "二维码截屏识别"))
        self.pushButton.setText(_translate("MainWindow", "截屏识别"))
        self.pushButton_2.setText(_translate("MainWindow", "打开全部"))

    # 以下为自定义函数,用来实现自定义功能,将与各个组件的相应事件绑定
    def grab(self):
        img = ImageGrab.grab()  # 截屏
        results = pyzbar.decode(image=img, symbols=[pyzbar.ZBarSymbol.QRCODE])  # 识别二维码
        self.listWidget.clear()  # 先清空以前的信息
        for i, result in enumerate(results):
            url = result.data.decode('utf-8')
            # print(url)
            self.listWidget.insertItem(i, url)  # 这里的url是str,不是QListWidgetItem,主打方便

    def open_url(self):
        for i in range(self.listWidget.count()):  # count计数有多少个item,便于按row获取item
            webbrowser.open(url=self.listWidget.item(i).text())  # item(row)获取元素,text()返回str

    def double_open(self):
        url = self.listWidget.selectedItems()[0].text()  # 选中的item可以是多个,但是double的时候只会有一个所以[0]
        webbrowser.open(url=url)


if __name__ == '__main__':
    # 必须的app和sys.exit(和tk.mainloop一样)
    app = QtWidgets.QApplication(sys.argv)

    # 将创建的ui实例化,应用起来
    ui = Ui_MainWindow()
    MainWindow = QtWidgets.QMainWindow()
    # ui只是框架,需要传入一个QMainWindow对象作为实体来应用该ui
    ui.setupUi(MainWindow)
    # 显示ui(窗口)
    MainWindow.show()

    sys.exit(app.exec_())

# 另一种实例化方式
# 在Ui_MainWindow中加入带参数的初始化方法:
def __init__(self, mainwindow):
    self.setupUi(mainwindow)  # 把setupUi放到构造函数来调用
Mainwindow = QtWidgets.QMainWindow()
ui = Ui_MainWindow(Mainwindow)  ##### 注意这里一定要用一个变量接收实例化对象!!!!
Mainwindow.show()

# 这样做可以在grab方法那实现Ui的隐藏,使得截屏时隐藏该应用窗口,
# self.win = mainwindow
# self.win.hide()  # 隐藏窗口
# self.win.show()  # 重新展示窗口
# self.win.showMinimized()  # 最小化窗口
# self.win.showNormal()  # 正常展示窗口
# self.win.showMaximized()  # 最大化窗口
# 截屏隐藏窗口的源码详见下面github地址

github地址:faf4r/QR: 二维码识别软件 (github.com)

posted @ 2023-07-08 01:13  faf4r  阅读(194)  评论(0编辑  收藏  举报