【PySide6】使用PySide6创建您的第一个应用程序

使用Python和Qt创建一个简单的“Hello World!”应用程序

在本教程中,我们将学习如何使用 PySide 来使用 Python 创建桌面应用程序。首先,我们将创建一系列简单的窗口,以确保 PySide 正常工作,并介绍一些基本概念。然后,我们将简要了解事件循环及其与 Python 中 GUI 编程的关系。最后,我们将介绍 Qt 的 QMainWindow,它提供了一些常用的界面元素,如工具栏和菜单。这些将在后续的教程中更详细地探讨。

创建一个应用程序

让我们创建我们的第一个应用程序吧!首先创建一个新的 Python 文件 —— 你可以随意命名(例如 app.py),并将其保存在可访问的地方。我们将在这个文件中编写我们的简单应用程序。

随着我们的进展,我们将在这个文件中进行编辑,您可能想要回到代码的早期版本,因此请记得定期备份。

以下是应用程序的源代码。请逐字输入,并小心不要出错。如果出现错误,Python 将会提示您出了什么问题。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
from PySide6.QtWidgets import QApplication, QWidget

# 仅在需要访问命令行参数时使用
import sys

# 每个应用程序只需要一个 QApplication 实例。
# 传入 sys.argv 可以允许应用程序使用命令行参数。
# 如果你确定不会使用命令行参数,也可以使用 QApplication([])。
app = QApplication(sys.argv)

# 创建一个 Qt 窗口小部件,它将成为我们的窗口。
window = QWidget()
window.show() # 重要!!!!! 窗口默认是隐藏的。

# 启动事件循环。
app.exec()

# 在你退出并且事件循环停止之前,你的应用程序不会到达这里。

运行这段代码! 您现在将会看到您的窗口。Qt 自动创建了一个带有普通窗口装饰的窗口,您可以像任何窗口一样拖动它并调整其大小。

您所看到的将取决于您在哪个平台上运行此示例。下面的图像显示了在 Windows、macOS 和 Linux(Ubuntu)上显示的窗口。

Our window, as seen on Windows, macOS and Linux.

让我们逐步解释代码

首先,我们导入了应用程序中需要的 PySide 类。我们从QtWidgets模块中导入了QApplication类,它是应用程序的处理程序,以及 QWidget 类,它是一个基本的空 GUI 小部件。

1
from PySide6.QtWidgets import QApplication, QWidget

Qt 的主要模块包括 QtWidgetsQtGuiQtCore

你可以使用 from <module> import * 这种方式,但是在 Python 中这种全局导入通常是不被推荐的,所以我们在这里会避免使用它。

接下来,我们创建一个 QApplication 的实例,将 sys.argv 作为参数传入,其中 sys.argv 是一个 Python 列表,包含了传递给应用程序的命令行参数。

1
app = QApplication(sys.argv)

如果你知道你不会使用命令行参数来控制 Qt,你可以传入一个空列表,例如:

1
app = QApplication([])

接下来,我们使用变量名 window 创建一个 QWidget 的实例。

1
2
window = QWidget()
window.show()

在 Qt 中,所有顶级小部件都是窗口,也就是说,它们没有父级,并且不嵌套在另一个小部件或布局中。这意味着你可以在任何你喜欢的小部件上创建一个窗口。

小部件如果没有父级,默认情况下是不可见的。因此,在创建窗口对象后,我们必须始终调用 .show() 方法使其可见。你可以移除 .show() 并运行应用程序,但是你将无法退出它!

窗口是什么? - 承载应用程序的用户界面 - 每个应用程序至少需要一个窗口(但可以有多个) - 当最后一个窗口关闭时,默认情况下应用程序会退出

最后我们调用app.exec()来启动事件循环。

什么是事件循环?

在将窗口显示在屏幕上之前,有几个关键概念需要介绍一下,这些概念涉及到 Qt 世界中应用程序的组织方式。如果你已经熟悉事件循环,可以安全地跳过到下一节。

每个 Qt 应用程序的核心是 QApplication 类。每个应用程序都需要一个 —— 而且只能有一个 —— QApplication 对象来运行。这个对象承载着你的应用程序的事件循环 —— 控制所有用户与 GUI 的交互的核心循环。

Our window, as seen on Windows, macOS and Linux.

与你的应用程序的每次交互 —— 无论是按键、鼠标点击还是鼠标移动 —— 都会生成一个事件,然后被放置在事件队列中。在事件循环中,队列在每次迭代时都会被检查,如果发现等待处理的事件,就会将事件和控制权传递给特定的事件处理程序。事件处理程序处理完事件后,将控制权再次传递回事件循环,等待更多的事件。每个应用程序只有一个正在运行的事件循环。

QApplication 类 - QApplication 承载着 Qt 事件循环 - 需要一个 QApplication 实例 - 你的应用程序在事件循环中等待,直到有操作发生 - 在任何时候只有一个事件循环

下划线是因为在 Python 2.7 中 exec 是一个保留字。PySide 处理这个问题的方法是在 Qt 库中使用的名称后添加下划线。例如,你还会看到小部件上的 .print_() 方法。

QMainWindow

正如我们在上一部分发现的那样,在 Qt 中任何小部件都可以成为窗口。例如,如果你将 QtWidgets 替换为 QPushButton。在下面的示例中,你将得到一个带有单个可点击按钮的窗口。

1
2
3
4
5
6
7
8
9
import sys
from PySide6.QtWidgets import QApplication, QPushButton

app = QApplication(sys.argv)

window = QPushButton("Push Me")
window.show()

app.exec()

这很好,但实际上并不是非常有用 —— 很少有需要只包含单个控件的用户界面!但是,正如我们稍后将发现的那样,使用布局将小部件嵌套在其他小部件中的能力意味着你可以在一个空的 QWidget 内构建复杂的用户界面。

但是,Qt 已经为你提供了解决方案 —— QMainWindow。这是一个预制的小部件,提供了许多标准窗口功能,你在应用程序中会用到,包括工具栏、菜单、状态栏、可停靠的小部件等等。我们稍后会看到这些高级特性,但现在,我们将在我们的应用程序中添加一个简单的空 QMainWindow

1
2
3
4
5
6
7
8
9
10
import sys
from PySide6.QtWidgets import QApplication, QMainWindow

app = QApplication(sys.argv)

window = QMainWindow()
window.show()

# 启动事件循环.
app.exec()

运行这段代码!你将会看到你的“主窗口”,但事实上它和之前的看起来没有区别

所以我们的 QMainWindow 目前并不是很有趣。我们可以通过添加一些内容来修复这个问题。如果你想创建一个自定义窗口,最好的方法是子类化 QMainWindow,然后在 __init__ 块中包含窗口的设置。这样可以使窗口的行为自包含。我们可以添加我们自己的 QMainWindow 子类 —— 把它称为 MainWindow,以保持简单。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
import sys

from PySide6.QtCore import QSize, Qt
from PySide6.QtWidgets import QApplication, QMainWindow, QPushButton


# 子类QMainWindow可自定义应用程序的主窗口
class MainWindow(QMainWindow):
def __init__(self):
super().__init__()

self.setWindowTitle("My App")

button = QPushButton("Press Me!")

# 设置窗口的中心部件。
self.setCentralWidget(button)


app = QApplication(sys.argv)

window = MainWindow()
window.show()

app.exec()

在这个演示中,我们使用了一个 QPushButton。核心的 Qt 小部件总是从 QtWidgets 命名空间中导入,就像 QMainWindowQApplication 类一样。当使用 QMainWindow 时,我们使用 .setCentralWidget 方法将一个小部件(这里是一个 QPushButton)放置在 QMainWindow 中 —— 默认情况下,它占据整个窗口。我们将在布局教程中讨论如何向窗口添加多个小部件。

当你子类化一个Qt类时,你必须始终调用super __init__函数,以便让Qt设置对象。

在我们的__init__块中,我们首先使用.setWindowTitle()来更改主窗口的标题。然后我们将第一个小部件——QPushButton——添加到窗口的中间。这是 Qt 中可用的基本小部件之一。在创建按钮时,您可以传递您想要按钮显示的文本。

最后,我们在窗口上调用.setCentralWidget()。这是一个特定于QMainWindow的函数,允许您设置放在窗口中间的小部件。

运行它!现在您将再次看到您的窗口,但这次中间有QPushButton小部件。按下按钮将不会产生任何效果,我们接下来会解决这个问题。

Our window, as seen on Windows, macOS and Linux.

我们将很快详细介绍更多小部件,但如果您不耐烦,并希望提前尝试,您可以查看QWidget文档。尝试向您的窗口添加不同的小部件!

调整窗口和小部件的大小

窗口当前可以自由调整大小——如果您用鼠标抓住任何角落,可以拖动并调整到任意大小。虽然让用户调整应用程序的大小是很好的,但有时您可能希望对最小或最大大小设置限制,或者锁定窗口为固定大小。

在 Qt 中,使用QSize对象定义大小。它按照宽度和高度的顺序接收参数。例如,以下代码将创建一个固定大小为 400x300 像素的窗口。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
import sys

from PySide6.QtCore import QSize, Qt
from PySide6.QtWidgets import QApplication, QMainWindow, QPushButton


# Subclass QMainWindow to customize your application's main window
class MainWindow(QMainWindow):
def __init__(self):
super().__init__()

self.setWindowTitle("My App")

button = QPushButton("Press Me!")

self.setFixedSize(QSize(400, 300))

# Set the central widget of the Window.
self.setCentralWidget(button)


app = QApplication(sys.argv)

window = MainWindow()
window.show()

app.exec()

运行它!您将看到一个固定大小的窗口——尝试调整此窗口的大小,你会发现无法调整。

Our window, as seen on Windows, macOS and Linux.

在 Windows 和 Linux 上,右上角控件将被禁用。在 macOS 上,您可以最大化应用程序以填充屏幕,但中央小部件不会调整大小。

除了使用.setFixedSize()外,您还可以调用.setMinimumSize()和.setMaximumSize()分别设置最小和最大尺寸。自己尝试一下吧!

你可以在任何小部件上使用这些调整大小的函数

在本节中,我们介绍了 QApplication 类、QMainWindow 类、事件循环,并尝试向窗口添加了一个简单的小部件。在下一节中,我们将探讨 Qt 提供的用于小部件和窗口相互通信以及与您自己代码通信的机制。

原文信息:《Creating your first app with PySide6》
原作者:Martin Fitzpatrick
出处:https://www.pythonguis.com/tutorials/pyside6-creating-your-first-window/
免责声明:本翻译内容仅代表翻译者的个人观点与理解,原作者对此翻译版本并未进行认可,翻译过程中可能存在误差,读者应自行核实原文内容。