基于Pyqt5快速构建应用程序详细教程

一、介绍

        图形用户界面,更广为人知的名称是 GUI,是当今大多数个人计算机的一个特征。 它为不同计算技能水平的用户提供了直观的体验。 尽管 GUI 应用程序可能会使用更多资源,但由于其点击式特性,它们通常对用户友好。

        PyQt 是可用于在 Python 中开发跨平台 GUI 应用程序的工具包之一。 如果您已经牢牢掌握这门语言,那么它功能强大且易于学习。

        本文将向您介绍使用 PyQt 构建 GUI 的基础知识。 它要求您具备 Python 和面向对象编程的基础知识。 我们的重点将主要放在 PyQt 上,而不是解释 Python 概念。在本文末尾会放上一个

基于pyqt5+GDAL带界面的遥感指数(模型)小软件的资源,供大家学习。

二、什么是 PyQt

        PyQt 是跨平台应用程序开发框架 Qt 的 Python 绑定。 使用 PyQt 可以让您受益于使用像 Python 这样简单但功能强大的语言开发 GUI 应用程序。 它公开了 Qt API 的所有功能。

        在本文中,我们将使用 PyQt5。 它需要 Python v3.5 或更高版本,但您也可以使用较早版本的 Python 进行构建。 

三、安装PyQt

        对于商业许可版本的 PyQt,您必须先获得许可证才能安装。 要安装 GPL 许可版本,请运行以下命令创建虚拟环境并安装 PyQt5。 虽然您可以全局安装 PyQt,但建议您使用虚拟环境。

# Create virtual environment
python3 -m venv env

# Activate virtual environment
source env/bin/activate

# Install PyQt5
pip install PyQt5

        有关详细的安装说明,您应该查看您要使用的特定 PyQt 版本的文档。 它包含安装 GPL 和商业版本的说明。 该文档还提供故障排除提示,以防您遇到某些错误。

四、PyQt开始构建简单GUI程序

        让我们通过构建一个简单的“hello world”GUI 来体验一下 PyQt。 构建这个简单的应用程序将使后续部分的事情变得容易得多。

        在我们开始之前,这里值得一提的是 PyQt 使用驼峰命名法和属性名称。 在整篇文章中,为了保持一致性,我们将在命名变量和函数时使用驼峰式命名,而不是 Python 中推荐的命名约定。

        目前,我们将有意使事情保持简单和最小化。 我假设您在项目目录中创建了一个 app.py 文件; 您可以按照以下步骤将每个步骤中的代码行添加到您的 app.py 文件中。

4.1 导入需要的类

         PyQt 带有几个内置模块。 但是,在构建 GUI 时,您最常与之交互的模块是 QtWidgets 模块。 它具有您将用于创建 GUI 的类。

        因为我们的目标是创建最基本的“hello world”GUI,所以我们将只使用 QApplication 和 QWidgets 类。 首先像这样导入它们:

from PyQt.QtWidgets import QApplication, QWidgets

        您可以以相同的方式导入要在应用程序中使用的其他类。

4.2 初始化应用程序

        我们需要通过创建 QApplication 的实例来初始化应用程序。 它负责管理应用程序的主要设置和控制流。 因此,您应该在创建与用户界面相关的任何其他对象之前实例化此类。

application = QApplication([])

        有关 QApplication 类职责的更多见解,请查看 Qt 文档。

        在上面的代码中,我们向 QApplication 传递了一个空数组,但如果您希望应用程序从命令行接收参数,您也可以传递 sys.argv。 如果您将 sys.argv 作为参数传递,请务必导入 sys。

4.3 创建主窗口

        主窗口,也称为顶层窗口,是一个没有父窗口的小部件。 每个 GUI 都必须有一个主窗口。

        现在,我们将创建一个 QWidget 实例并将其作为我们的主窗口,如下所示:

mainWindow = QWidget()
mainWindow.setGeometry(0, 0, 350, 400)
mainWindow.setWindowTitle('Hello World')

        创建 Qwidget 实例后,您可以调用其他几种方法。 对于我们的简单 GUI,我们调用了 setGeometry 方法和 setWindowTitle 方法。

        setGeometry 方法用于在屏幕上定位 GUI 并设置其尺寸。 它的函数签名是 setGeometry(x, y, width, height)。 前两个参数指定窗口在屏幕上的 x 和 y 坐标,width 和 height 分别用于设置窗口的宽度和高度。

        setWindowTitle 方法,顾名思义,用于设置应用程序的标题。 您可以将标题作为字符串参数传递。 如果您不自己设置,窗口将没有标题。

4.4 显示主窗口

        默认情况下,我们在上一步中创建的窗口是不可见的。 我们需要通过调用 show 方法来显示它:

mainWindow.show()

4.5 启动事件循环

        最后,您需要通过调用 application.exec 方法来启动事件循环:

application.exec()

        您也可以改用 application.exec_() 来启动事件循环。完成上述所有五个步骤后,您的 app.py 文件应包含以下代码:

from PyQt5.QtWidgets import QWidget, QApplication

application = QApplication([])

mainWindow = QWidget()

mainWindow.setGeometry(0, 0, 350, 400)
mainWindow.setWindowTitle('Hello World')

mainWindow.show()

application.exec()

        与任何其他 Python 脚本一样,您需要使用命令 python3 app.py 来运行 app.py。 您应该能够看到显示的窗口。 窗口的外观在很大程度上取决于您的系统。 在 Linux 上,它应该类似于下图。

 五、PyQt 中的主要概念

        我们刚刚创建了我们的第一个“hello world”GUI。 现在让我们看看一些主要的概念,它们将拓宽我们对 PyQt 的了解。 对这些概念有一定程度的熟悉对于构建生产级 GUI 是必要的。

5.1 Widgets

        像大多数 GUI 工具包一样,小部件是 PyQt GUI 的构建块。 您可以使用小部件来显示数据、接收用户输入,或将其用作对其他相关小部件进行分组的容器。

        大多数小部件嵌套在其他小部件中,但是,总有一个小部件没有父级。 如前所述,没有父级的小部件称为窗口。

        在 PyQt 中创建小部件的主要类是 QWidgets 类。 在 PyQt 中创建 UI 的所有元素要么是 QWidgets 类的子类,要么与 QWidgets 类结合使用。

        您可以在 PyQt 或 Qt 文档中阅读一些小部件类。 我们不能在这里一一列举。 一些基本的小部件类包括:

  • QLabel用于显示文字和图片
  • QPushButton 用于创建命令按钮
  • QLineEdit 用于创建单行文本编辑器
  • QRadioButton 用于创建带有文本标签的单选按钮

        让我们向“hello world”GUI 添加一个简单的 pushButton 小部件:

from PyQt5.QtWidgets import QWidget, QApplication, QPushButton

application = QApplication([])

mainWindow = QWidget()
mainWindow.setGeometry(0, 0, 350, 400)
mainWindow.setWindowTitle('Button Widget')

pushButton = QPushButton(parent=mainWindow, text='Click me')

mainWindow.show()
application.exec()

        运行上面的代码将创建一个类似于下图的窗口。

 5.2 事件循环

        大多数 GUI 工具包都是事件驱动的。 PyQt 也不例外。 事件可以源自用户与应用程序的交互,例如单击按钮、填写输入文本、单击链接或关闭窗口。 事件也可以来自窗口系统或其他来源。 事件循环负责管理这些事件。

        调用 .exec 方法将触发事件循环,正如我们在构建“hello world”GUI 时强调的那样。 循环等待事件发生并在事件发生时做出响应。 如果它收到 Terminate 事件,它会终止并退出应用程序。

        正是通过这种事件响应功能,您可以使用信号和槽向 GUI 添加交互性。 我们将在下面的部分中了解信号和槽。

5.3  信号和槽

        在前面的部分中,我们了解了如何使用小部件创建 GUI 的可见组件。 您可以通过信号和槽向 GUI 添加交互性。 我们在“hello world”GUI 中添加了一个按钮小部件,但目前单击该按钮不会执行任何操作。

                通常,单击按钮应该触发一个动作,例如打开另一个小部件、关闭小部件或登录。您需要信号和槽来响应此类用户操作或小部件状态的更改。

信号是小部件在发生某些事情时发出的通知。 它可以是单击按钮、移动鼠标或更改文本输入字段。 不同的小部件发出不同的信号。 例如,一个按钮部件在被点击时发出 clicked 信号。 按钮小部件还发出其他鲜为人知的信号,例如按下、释放和切换信号。 要了解特定小部件发出的信号,您需要阅读小部件对应类的文档。

        插槽是在小部件发出特定信号后调用的函数或方法。 几个小部件带有预定义的插槽。 但是,您也可以定义槽来处理感兴趣的信号。

        为了说明我们刚刚学到的内容,让我们向我们的按钮小部件添加一个插槽,以便它响应单击信号运行:

from PyQt5.QtWidgets import QWidget, QApplication, QPushButton

application = QApplication([])

mainWindow = QWidget()
mainWindow.setGeometry(0, 0, 350, 400)
mainWindow.setWindowTitle('Slot and Signal')

def clickedSlot():
    print('The button has been clicked')

pushButton = QPushButton(parent=mainWindow, text='Click me')
pushButton.clicked.connect(clickedSlot)

mainWindow.show()
application.exec()

        运行上面的代码并单击按钮后,您应该会在终端上看到文本 The button has been clicked。

5.4 PyQT布局管理

        到目前为止,我们只了解了 PyQt 的最基本组件。 在真实世界的应用程序中,您将在同一个窗口中处理多个小部件。 幸运的是,Qt 有多种功能可用于管理应用程序 UI 中的小部件布局。 您可以使用这些功能来描述如何排列小部件。 只要空间发生变化,布局就会自动调整小部件的大小和位置。 因此,UI 仍然可用。

        虽然 PyQt 有多种布局形式,但我们将在本文中查看水平、垂直、网格和表单布局。 您可以在 PyQt 或 Qt 文档中阅读其他内容。 每个提到的布局都有一个相应的内置布局类。 这些类是:

  • QHBoxLayout
  • QVBoxLayout
  • QGridLayout
  • QFormLayout

(1) 水平布局

        您可以使用内置的 QHBoxLayout 类来水平布置小部件,通常是从左到右。 对于从右到左的语言,它还可以从右到左排列小部件。

        在下面的代码中,我修改了“hello world”GUI 以在水平布局中显示五个图像。 为避免重复,我使用 for 循环将图像添加到布局中。 在运行此代码之前,请确保 cat.jpg 文件中有图像:

from PyQt5.QtGui import QPixmap
from PyQt5.QtWidgets import (
    QLabel,
    QWidget,
    QApplication,
    QHBoxLayout,
)

application = QApplication([])

mainWindow = QWidget()

mainWindow.setGeometry(0, 0, 350, 400)
mainWindow.setWindowTitle('Horizontal Layout')

horizontalLayout = QHBoxLayout()

for num in range(6):
    label = QLabel()
    pixmap = QPixmap('cat.jpg')
    label.setPixmap(pixmap)
    horizontalLayout.addWidget(label)

mainWindow.setLayout(horizontalLayout)
mainWindow.show()

application.exec()

        在 PyQt 中,您可以使用 QLabel 小部件渲染图像。 从 QtGui 模块导入 QPixmap 类实例后,您首先要创建它。 使用 QLabel 类的 setPixmap 方法将其设置在标签小部件上,如上面的 for 循环所示。

        在进入下一节之前,您可以先玩一下代码。 您可以布置其他小部件,例如按钮,而不是布置图像。

        上面的代码应该创建一个类似于下图的 GUI。

 (2) 竖直布局

        与 QHBoxLayout 类从左到右或从右到左水平放置小部件不同,QVBoxLayout 类从上到下垂直放置小部件。

        下面的代码显示了如何使用 QVBoxLayout 类进行垂直布局管理。 它与水平布局非常相似:

mainWindow = QWidget()

mainWindow.setGeometry(0, 0, 350, 400)
mainWindow.setWindowTitle('Vertical Layout')

verticalLayout = QVBoxLayout()

for num in range(6):
    label = QLabel()
    pixmap = QPixmap('cat.jpg')
    label.setPixmap(pixmap)
    verticalLayout.addWidget(label)

mainWindow.setLayout(verticalLayout)
mainWindow.show()

application.exec()

        运行上面的代码应该创建一个 GUI,其中的图像从上到下排列,类似于下图。

 (3)格网布局

        网格布局管理涉及在二维网格中布置小部件。 QGridLayout 是一个方便的内置类,用于执行此操作。 在网格布局中,一个项目可以占据两个网格。 您还可以在网格项中嵌套另一个布局。 它使构建更复杂的 GUI 变得容易得多。

        您可以创建 QGridLayout 类的实例并使用 addWidget 方法向其添加小部件。 与前面的部分一样,我循环将图像添加到网格中,以避免在下面的代码中重复。 也可以在用小部件填充网格时跳过网格:

from PyQt5.QtGui import QPixmap
from PyQt5.QtWidgets import (
    QLabel,
    QWidget,
    QApplication,
    QGridLayout,
)

application = QApplication([])

mainWindow = QWidget()

mainWindow.setGeometry(0, 0, 350, 400)
mainWindow.setWindowTitle('Grid Layout')

gridLayout = QGridLayout()

for row in range(3):
    for col in range(3):
        label = QLabel()
        pixmap = QPixmap('cat.jpg')
        label.setPixmap(pixmap)
        gridLayout.addWidget(label, row, col)

mainWindow.setLayout(gridLayout)
mainWindow.show()

application.exec()

        因为您将小部件放置在二维网格中,所以在将每个小部件添加到布局时需要指定每个小部件的位置。

        运行上面的代码后,您的“hello world”GUI 应该如下图所示。

 (4) 表格布局

        表单布局主要用于管理输入小部件及其相关标签。 它由排列成标签字段对的小部件行组成。 您需要使用 QFormLayout 类在表单布局中排列小部件,如下面的代码所示:

from PyQt5.QtWidgets import (
    QGroupBox,
    QLabel,
    QLineEdit,
    QPlainTextEdit,
    QRadioButton,
    QSpinBox,
    QVBoxLayout,
    QWidget,
    QApplication,
    QFormLayout,
)

application = QApplication([])

mainWindow = QWidget()

mainWindow.setGeometry(0, 0, 350, 400)
mainWindow.setWindowTitle('Form Layout')

formLayout = QFormLayout()

nameLabel = QLabel('Name')
nameField = QLineEdit()

ageLabel = QLabel('Age')
ageField = QSpinBox()
ageField.setMinimum(0)
ageField.setMaximum(130)


sexLabel = QLabel('Sex')
sexGroup = QGroupBox()
verticalLayout = QVBoxLayout()

for sex in ['Male', 'Female', 'Other']:
    radioButton = QRadioButton(sex)
    verticalLayout.addWidget(radioButton)

sexGroup.setLayout(verticalLayout)

commentLabel = QLabel('Comments')
commentField = QPlainTextEdit()


formLayout.addRow(nameLabel, nameField)
formLayout.addRow(ageLabel, ageField)
formLayout.addRow(sexLabel, sexGroup)
formLayout.addRow(commentLabel, commentField)

mainWindow.setLayout(formLayout)
mainWindow.show()

application.exec()

        运行上面的代码可以看到类似于下图的 GUI。 您可以看到标签字段对小部件。 每行都有一个标签小部件和右侧相应的字段小部件。

         您可以在 PyQt 或 Qt 文档中阅读其他形式的布局。

六、创建菜单栏

        菜单是大多数 GUI 应用程序的特征。 桌面 GUI 通常在主窗口的顶部有菜单。 一些下拉菜单具有悬停时打开的子菜单。 下图显示了桌面 GUI 上典型菜单的外观。

        如上一节所述,QMainWindow 类提供了一种布局,可以开箱即用地向 GUI 添加菜单栏。 要创建菜单栏,您需要使用 menuBar 方法。

        下面是在上图中创建下拉菜单的代码。 我使用 QAction 类创建动作并将它们添加到相应的菜单以创建下拉菜单:

from PyQt5.QtWidgets import QMainWindow, QApplication, QAction

class MainWindow(QMainWindow):
    def __init__(self, parent=None):
        super().__init__(parent)

        self.setWindowTitle('Dropdown Menu')
        self.setGeometry(0, 0, 350, 400)
        self.addMenu()

    def addMenu(self):

        # Create menu bar
        menuBar = self.menuBar()

        # Add menu items
        fileMenu = menuBar.addMenu('File')
        helpMenu = menuBar.addMenu('Help')

        # Create actions

        visitWebsiteAction = QAction('Visit Our Website', self)
        fileBugReportAction = QAction('File a Bug Report', self)

        # Add dropdown menu items on the Help menu

        helpMenu.addAction(visitWebsiteAction)
        helpMenu.addAction(fileBugReportAction)

        # Add 'Follow Us' dropdown menu item on the Help menu

        followUs = helpMenu.addMenu('Follow Us')

        # Social media actions

        twitterAction = QAction('Twitter', self)
        githubAction = QAction('GitHub', self)

        # Add actions

        followUs.addAction(twitterAction)
        followUs.addAction(githubAction)



if (__name__ == '__main__'):
    application = QApplication([])
    mainWindow = MainWindow()
    mainWindow.show()
    application.exec()

七、案例

        基于pyqt5实现的遥感应用软件,可根据需求进行改动。目前里面是一个NDVI指数计算的样例。逻辑与界面分离,运行时不会界面卡死。运行结果如下图所示。

        资源地址如下https://download.csdn.net/download/u010329292/87708832:需要的小伙伴可以下载学习~~

猜你喜欢

转载自blog.csdn.net/u010329292/article/details/130302941