PyQt5安装与基本使用

PyQt5是基于Qt5设计思路的Python图形用户界面工具包,可以协助用户创建图形界面。

PyQt5文档:

安装

PyQt5主程序包

在控制台中执行:

pip install PyQt5

PyQt5工具包

如果您的计算机上已安装Qt环境或QtCreator等工具,可以跳过此步骤。

在控制台中执行:

pip install PyQt5-Tools

第三方控件

此处以QCustomPlot绘图控件的PyQt5版本为例。

pip install QCustomPlot_PyQt5

建立窗体

推荐采用窗体逻辑和业务代码分离的设计,以保证程序的可维护性。

绘制窗体

您可以使用QtCreator、Qt Designer等工具可视化地绘制窗体。如果您已经安装了Qt开发环境或QtCreator,您可以直接启动这些工具。如果您使用PyQt5-Tools,您可以在Qt包根目录的site-packages\qt5_applications\Qt\bin\目录中找到designer.exe界面设计器。

请注意:如果您使用了“提升控件”功能将控件提升为第三方控件,请确保“头文件”一项使用包含该第三方控件的包的名称(同时添加.h扩展名)。例如,若您将QWidget提升为QCustomPlot,则应配置“提升的类名”为QCustomPlot,“头文件”为QCustomPlot_PyQt5.h

这里假设您将窗体文件保存为MainWindow.ui

将窗体文件转换为Python文件

PyQt无法直接识别UI格式的窗体文件,因此您需要将其转换为可执行的Python文件。

在控制台中执行:

python -m PyQt5.uic.pyuic MainWindow.ui -o ui_MainWindow.py

此时,得到的ui_MainWindow.py文件即为窗体代码文件,该文件定义了窗体UI基类Ui_MainWindow,包含了用于初始化窗体上的控件的setupUi()函数。

建立窗口代码文件

由于此时窗体界面信息和业务逻辑是分离的,因此需要创建名为MainWindow.py的业务代码文件,定义名为MainWindow的、同时继承QMainWindowUi_MainWindow基类的业务代码类:

# PyQt5 modules
from PyQt5.QtCore import *
from PyQt5.QtWidgets import *
 
# QCustomPlot for PyQt5
from QCustomPlot_PyQt5 import *
 
# UI File
from ui_MainWindow import Ui_MainWindow
 
# MainWindow implementation
class MainWindow(QMainWindow, Ui_MainWindow) :
 
    # MainWindow constructor
    def __init__(self) :
        # Initialize base classes
        super().__init__()
 
        # Initialize widgets
        self.setupUi(self)
 
        # Application init
        pass
    #End Sub
 
    # MainWindow destructor
    def __del__(self) :
        pass
    #End Sub
 
    # Do cleaning works when closing
    def closeEvent(self, evtEvent) :
        # Generally you don't need to delete an object manually
        #self.__del__()
 
        evtEvent.accept()
    #End Sub
 
#End Class

建立程序入口点

和基于C++的Qt一样,PyQt需要先建立QApplication对象启动事件循环,随后执行主窗口显示等任务,最后将执行结果返回给操作系统。此处将程序入口写入Main.py文件中:

# Public libraries
import sys
 
# PyQt5 modules
from PyQt5.QtWidgets import QApplication
 
# MainWindow classes
from MainWindow import MainWindow
 
# Main entry point
if __name__ == "__main__" : 
    # Create QApplication object and start main event loop
    appCurrent = PyQt5.QtWidgets.QApplication(sys.argv)
 
    # Show main window
    frmMainWindow = MainWindow()
    frmMainWindow.show()
 
    # Wait until main event loop exits
    sys.exit(appCurrent.exec_())
#End If

运行Main.py脚本,即可启动并展示主窗口。

使用信号与槽

PyQt的信号(Signal)与槽(Slot)思路与C++版本的Qt是一致的。但是在定义和使用时存在略微差异。

定义信号

任何继承自PyQt5.QtCore.QObject或其派生类的类均可定义类型为PyQt5.QtCore.pyqtSignal的对象实例,并将该对象实例作为信号使用:

SampleSignalWithNoParameters = pyqtSignal()

PyQt5.QtCore.pyqtSignal的构造函数可以输入一个列表,表示该信号可以传递的参数的类型。将多个数据类型使用方括号“[]”括起表示该参数可以传递多种类型的信号。例如,若一个信号的第一个参数必须为整数,而第二个参数可以为整数或字符串,则可以使用下面的方式定义:

SampleSignalWith2Parameters = pyqtSignal(int, [int,str])

定义槽

槽函数的定义与常规成员函数一致。

连接信号与槽

信号对象提供的PyQt5.QtCore.pyqtSignal.connect()函数可用于将信号与槽连接:

objEmitter.SampleSignal.connect(objReceiver.SampleSlot)

信号对象提供的PyQt5.QtCore.pyqtSignal.disconnect()函数可用断开信号与槽的连接:

objEmitter.SampleSignal.disconnect(objReceiver.SampleSlot)

发射信号

信号对象提供的PyQt5.QtCore.pyqtSignal.emit()函数可用于发射信号并传递参数:

self.SampleSignal.emit(objParam1, objParam2, ...)

示例程序

SignalSlotTest.py:定义信号发生器类SignalEmitter和接收器类SignalReceiver

# PyQt5 modules
from PyQt5.QtCore import *
 
# Sample signal emitter
class SignalEmitter(QObject) :
    # Sample signal with no parameters
    SampleSignalWithNoParameters = pyqtSignal()
 
    # Sample signal with 1 string parameter
    SampleSignalWith1Parameter = pyqtSignal(str)
 
    # Sample signal with 2 parameters, both can be Integer or String
    SampleSignalWith2Parameters = pyqtSignal([int,str], [int,str])
 
    # Signal emitting test
    def TestEmittingSignals(self) :
        # Emit signal with no parameters
        self.SampleSignalWithNoParameters.emit()
 
        # Emit signal with 1 parameter
        self.SampleSignalWith1Parameter.emit("Picsell Dois")
 
        # Emit signal with 2 parameters
        self.SampleSignalWith2Parameters.emit(245, "Suicune")
    #End Sub
#End Class
 
# Sample signal receiver
class SignalReceiver(QObject) :
    # Slot with no parameters
    def SampleSlotWithNoParameters(self) :
        print("SampleSlotWithNoParameters: Executed with no parameters received.")
    #End Sub
 
    # Slot with 1 parameter
    def SampleSlotWith1Parameter(self, sData : str) :
        print(f"SampleSlotWithWith1Parameter: Received {sData}")
    #End Sub
 
    # Slot with 2 parameters
    def SampleSlotWith2Parameters(self, iData1 : int, sData2 : str) :
        print(f"SampleSlotWithWith1Parameter: Received {iData1} and {sData2}")
    #End Sub
#End Class

Main.py:程序主入口。

# Public libraries
import sys
 
# PyQt5 modules
from PyQt5.QtWidgets import QApplication
 
# Signal emitter and receiver classes
from SignalSlotTest import SignalEmitter,SignalReceiver
 
# Main entry point
if __name__ == "__main__" : 
    # Create QApplication object and start main event loop
    appCurrent = QApplication(sys.argv)
 
    # Create signal emitter and receiver objects
    objEmitter = SignalEmitter()
    objReceiver = SignalReceiver()
 
    # Connect signals and slots
    objEmitter.SampleSignalWithNoParameters.connect(objReceiver.SampleSlotWithNoParameters)
    objEmitter.SampleSignalWith1Parameter.connect(objReceiver.SampleSlotWith1Parameter)
    objEmitter.SampleSignalWith2Parameters.connect(objReceiver.SampleSlotWith2Parameters)
 
    # Test emitting signals
    objEmitter.TestEmittingSignals()
 
    # Wait until main event loop exits
    #sys.exit(appCurrent.exec_())
#End If

参考资料

https://www.riverbankcomputing.com/static/Docs/PyQt5/

https://pypi.org/project/PyQt5/

https://pypi.org/project/QCustomPlot-PyQt5/

https://blog.csdn.net/weixin_42475060/article/details/130327901

https://www.nixgnauhcuy.cn/8d34424033d0/

https://blog.csdn.net/yg2496194392/article/details/129944809

https://blog.csdn.net/qq_62095154/article/details/122947262

https://www.cnblogs.com/chenhaiming/p/9930628.html

https://blog.csdn.net/huayunhualuo/article/details/102718509

it
除非特别注明,本页内容采用以下授权方式: Creative Commons Attribution-ShareAlike 3.0 License