接序篇:【Python篇】PyQt5 超详细教程——由入门到精通(序篇)
建议把代码复制到pycharm等IDE上面看实际效果,方便理解嗷❤️
在 PyQt5 中,信号(Signal) 和 槽(Slot) 是处理事件和交互的核心机制。信号代表某个事件的发生,而槽是信号触发后执行的函数。
clicked
信号。通过信号与槽机制,PyQt5 实现了控件之间的松散耦合,让事件处理更加灵活。
我们可以通过以下步骤使用信号与槽机制:
示例 1:按钮点击事件
from PyQt5.QtWidgets import QApplication, QMainWindow, QPushButton
import sys
class MainWindow(QMainWindow):
def __init__(self):
super().__init__()
self.setWindowTitle("信号与槽示例")
# 创建一个按钮
button = QPushButton("点击我", self)
# 将按钮的 clicked 信号连接到自定义槽函数
button.clicked.connect(self.button_clicked)
# 设置按钮为中央控件
self.setCentralWidget(button)
def button_clicked(self):
# 按钮点击后执行的操作
print("按钮被点击!")
app = QApplication(sys.argv)
window = MainWindow()
window.show()
sys.exit(app.exec_())
button.clicked.connect(self.button_clicked)
clicked
信号是 QPushButton
控件自带的信号,当按钮被点击时,信号会被触发。通过 connect()
方法,我们将这个信号连接到自定义的槽函数 button_clicked
,这样当按钮被点击时,程序会执行这个槽函数。self.button_clicked()
PyQt5 中每个控件都有多个内置信号。例如,QLineEdit
(文本输入框)控件有 textChanged
信号,表示文本发生了改变。
示例 2:处理文本输入框的信号
from PyQt5.QtWidgets import QApplication, QMainWindow, QLineEdit
import sys
class MainWindow(QMainWindow):
def __init__(self):
super().__init__()
self.setWindowTitle("QLineEdit 信号示例")
# 创建文本输入框
self.line_edit = QLineEdit(self)
# 连接文本改变的信号到自定义槽函数
self.line_edit.textChanged.connect(self.text_changed)
# 设置文本输入框为中央控件
self.setCentralWidget(self.line_edit)
def text_changed(self, text):
# 当用户修改文本时,显示当前输入的内容
print(f"用户输入: {text}")
app = QApplication(sys.argv)
window = MainWindow()
window.show()
sys.exit(app.exec_())
self.line_edit.textChanged.connect(self.text_changed)
QLineEdit
控件的 textChanged
信号,该信号会在用户每次修改文本时触发。每当用户输入或删除文本时,程序都会调用槽函数 text_changed
。self.text_changed(text)
text
是用户当前输入的内容。当文本内容改变时,这个槽函数会被自动调用,并打印出用户输入的文本。
有时候,PyQt5 提供的内置信号并不能满足所有需求。在这种情况下,你可以自定义信号,并将它们与槽函数关联起来。
示例 3:自定义信号
from PyQt5.QtCore import QObject, pyqtSignal
from PyQt5.QtWidgets import QApplication, QMainWindow, QPushButton
import sys
# 创建一个自定义的类,继承自 QObject
class Communicate(QObject):
# 定义一个自定义信号
my_signal = pyqtSignal()
class MainWindow(QMainWindow):
def __init__(self):
super().__init__()
self.setWindowTitle("自定义信号示例")
# 创建按钮
button = QPushButton("触发自定义信号", self)
button.clicked.connect(self.emit_custom_signal) # 连接按钮点击事件
# 创建自定义信号对象
self.comm = Communicate()
# 连接自定义信号到槽函数
self.comm.my_signal.connect(self.custom_slot)
# 设置按钮为中央控件
self.setCentralWidget(button)
def emit_custom_signal(self):
# 触发自定义信号
self.comm.my_signal.emit()
def custom_slot(self):
# 自定义信号触发时执行的操作
print("自定义信号被触发!")
app = QApplication(sys.argv)
window = MainWindow()
window.show()
sys.exit(app.exec_())
Communicate
类,继承自 QObject
。在这个类中,我们定义了一个信号 my_signal
,使用 pyqtSignal()
方法来创建。self.comm.my_signal.emit()
触发自定义信号。随后,这个信号会调用关联的槽函数 custom_slot
。custom_slot()
会执行并打印消息。
信号传递参数:大部分 PyQt5 内置信号都会传递参数。例如,textChanged
信号会传递当前文本内容,currentIndexChanged
信号会传递选中的下标。
断开信号与槽的连接:可以通过 disconnect()
方法断开信号与槽的连接。
button.clicked.disconnect(self.button_clicked)
在这一部分中,我们详细介绍了 PyQt5 的 信号与槽机制,这是 PyQt5 应用程序事件处理的核心。通过信号与槽机制,你可以让应用程序的控件彼此交互,实现复杂的用户界面行为。
关键点回顾:
在桌面应用程序中,用户经常需要与文件系统交互,例如打开文件、保存文件、选择文件夹等。为了让用户选择文件或保存文件,PyQt5 提供了一个标准化的控件,叫做 QFileDialog
。QFileDialog
是一个弹出窗口,允许用户通过系统文件浏览器来选择或保存文件。
QFileDialog
?QFileDialog
使用了操作系统的原生文件对话框,确保了跨平台的一致性。QFileDialog
打开文件我们将从如何使用 QFileDialog
打开文件并读取文件内容开始。这个过程包括:
import sys # 系统模块,用于控制程序退出
from PyQt5.QtWidgets import QApplication, QMainWindow, QPushButton, QFileDialog, QTextEdit
# 创建一个主窗口类
class MainWindow(QMainWindow):
def __init__(self):
super().__init__() # 调用父类的初始化方法
self.setWindowTitle("文件对话框示例") # 设置窗口标题
# 创建一个按钮
self.button = QPushButton("打开文件", self)
self.button.clicked.connect(self.open_file) # 连接按钮点击事件
# 创建一个文本编辑框,用于显示文件内容
self.text_edit = QTextEdit(self)
# 设置窗口布局
self.setCentralWidget(self.button) # 初始显示按钮
# 打开文件的函数
def open_file(self):
# 弹出文件对话框,让用户选择文件
file_name, _ = QFileDialog.getOpenFileName(self, "选择文件", "", "文本文件 (*.txt);;所有文件 (*)")
# 检查用户是否选择了文件
if file_name:
# 打开文件并读取内容
with open(file_name, 'r', encoding='utf-8') as f:
file_content = f.read() # 读取文件内容
# 将文件内容显示在文本编辑框中
self.text_edit.setText(file_content)
self.setCentralWidget(self.text_edit) # 切换显示文本编辑框
# 创建应用程序对象
app = QApplication(sys.argv)
# 创建主窗口对象
window = MainWindow()
window.show()
# 进入应用程序事件循环
sys.exit(app.exec_())
QFileDialog.getOpenFileName()
:
file_name
是用户选择的文件的路径。_
是过滤器信息,我们暂时不需要用到它,因此使用 _
来忽略。"文本文件 (*.txt);;所有文件 (*)"
表示用户只能看到 .txt
文件或所有类型的文件。我们可以根据应用场景自定义文件类型过滤器。
with open(file_name, 'r', encoding='utf-8') as f:
:
'r'
表示以只读模式打开文件,encoding='utf-8'
确保文件按 UTF-8 编码读取。QTextEdit
控件来显示读取到的文件内容。QTextEdit
是一个多行文本框,适合显示较大的文本内容。self.setCentralWidget(self.text_edit)
:将窗口中央控件从按钮切换为文本编辑框,这样用户可以在窗口中看到文件内容。
在文件对话框中,我们可以通过文件类型过滤器限制用户只能选择特定类型的文件。例如,下面是一些常见的文件类型过滤器:
"文本文件 (*.txt)"
:只显示 .txt
文件。"图片文件 (*.png *.jpg)"
:只显示 .png
和 .jpg
格式的图片文件。"所有文件 (*)"
:显示所有类型的文件。在 QFileDialog
中,多个文件类型可以通过 ;;
分隔。例如:
file_name, _ = QFileDialog.getOpenFileName(self, "选择文件", "", "图片文件 (*.png *.jpg);;所有文件 (*)")
QFileDialog
保存文件QFileDialog
不仅可以用于打开文件,还可以用于保存文件。让我们看看如何使用文件对话框来保存用户输入的内容到文件中。
import sys
from PyQt5.QtWidgets import QApplication, QMainWindow, QPushButton, QFileDialog, QTextEdit
class MainWindow(QMainWindow):
def __init__(self):
super().__init__()
self.setWindowTitle("保存文件示例")
# 创建文本编辑框,用户可以在其中输入文本
self.text_edit = QTextEdit(self)
self.setCentralWidget(self.text_edit)
# 创建保存按钮
save_button = QPushButton("保存文件", self)
save_button.clicked.connect(self.save_file)
self.text_edit.setFixedHeight(100) # 设置按钮的固定高度
self.text_edit.setFixedWidth(200)
# 保存文件的函数
def save_file(self):
# 弹出保存文件对话框,选择保存路径和文件名
file_name, _ = QFileDialog.getSaveFileName(self, "保存文件", "", "文本文件 (*.txt);;所有文件 (*)")
# 检查用户是否选择了保存文件的路径
if file_name:
# 获取文本框中的内容
file_content = self.text_edit.toPlainText()
# 将内容写入文件
with open(file_name, 'w', encoding='utf-8') as f:
f.write(file_content)
app = QApplication(sys.argv)
window = MainWindow()
window.show()
sys.exit(app.exec_())
QFileDialog.getSaveFileName()
: file_name
是用户选择的保存路径。如果用户取消操作,file_name
会是一个空字符串。self.text_edit.toPlainText()
: QTextEdit
文本框中获取用户输入的文本。toPlainText()
方法返回的是纯文本内容,不包含格式信息。open()
函数以写入模式 ('w'
) 打开文件,然后将用户输入的文本写入文件。如果文件不存在,系统会自动创建该文件。
PyQt5 的 QFileDialog
还允许用户同时选择多个文件。这在某些场景下非常有用,比如批量处理多个文件。
import sys
from PyQt5.QtWidgets import QApplication, QMainWindow, QPushButton, QFileDialog, QTextEdit, QVBoxLayout, QWidget
class MainWindow(QMainWindow):
def __init__(self):
super().__init__()
self.setWindowTitle("多文件选择示例")
# 创建按钮
button = QPushButton("选择多个文件", self)
button.clicked.connect(self.open_files)
# 创建文本编辑框,用于显示选择的文件路径
self.text_edit = QTextEdit(self)
self.text_edit.setReadOnly(True) # 设置为只读
# 创建一个中央窗口部件
central_widget = QWidget()
self.setCentralWidget(central_widget)
# 创建布局,并将按钮和文本编辑框添加到布局中
layout = QVBoxLayout()
layout.addWidget(button)
layout.addWidget(self.text_edit)
# 将布局应用到中央窗口部件
central_widget.setLayout(layout)
def open_files(self):
# 弹出文件对话框,允许用户选择多个文件
files, _ = QFileDialog.getOpenFileNames(self, "选择多个文件", "", "所有文件 (*)")
if files:
# 将所有文件路径显示在文本编辑框中
self.text_edit.setText('\n'.join(files))
app = QApplication(sys.argv)
window = MainWindow()
window.show()
sys.exit(app.exec_())
QFileDialog.getOpenFileNames()
: files
是用户选择的所有文件路径列表。'\n'.join(files)
:将文件路径列表转换为字符串,每个文件路径之间用换行符分隔,以便在文本框中展示多个文件路径。
在这一部分中,我们详细讲解了 PyQt5 中如何使用 QFileDialog
来处理文件的打开、保存以及多文件选择。QFileDialog
是 PyQt5 中一个强大且常用的对话框控件,允许用户与文件系统交互。
关键点:
QFileDialog.getOpenFileName()
:用于打开文件,返回用户选择的文件路径。QFileDialog.getSaveFileName()
:用于保存文件,允许用户选择保存路径。QFileDialog.getOpenFileNames()
:允许用户选择多个文件,返回文件路径列表。QTableWidget
是 PyQt5 提供的一个表格控件,允许你通过表格的形式展示数据。你可以将数据组织为行和列,类似于 Excel 表格或者 pandas 的 DataFrame。在应用程序中,表格控件非常适合展示结构化数据,如数据库查询结果、文件数据等。
首先,我们来看如何手动创建一个 QTableWidget
,并向其中填充一些数据。这里我们将创建一个 3 行 2 列的表格,并手动设置表头和每个单元格的数据。
import sys
from PyQt5.QtWidgets import QApplication, QMainWindow, QTableWidget, QTableWidgetItem
class MainWindow(QMainWindow):
def __init__(self):
super().__init__()
# 设置窗口标题
self.setWindowTitle("QTableWidget 示例")
# 创建一个 QTableWidget 表格,指定表格有 3 行 2 列
self.table_widget = QTableWidget(3, 2, self)
# 设置表格的表头
self.table_widget.setHorizontalHeaderLabels(["姓名", "年龄"])
# 填充表格的单元格数据
self.table_widget.setItem(0, 0, QTableWidgetItem("张三")) # 第1行第1列:张三
self.table_widget.setItem(0, 1, QTableWidgetItem("25")) # 第1行第2列:25
self.table_widget.setItem(1, 0, QTableWidgetItem("李四")) # 第2行第1列:李四
self.table_widget.setItem(1, 1, QTableWidgetItem("30")) # 第2行第2列:30
self.table_widget.setItem(2, 0, QTableWidgetItem("王五")) # 第3行第1列:王五
self.table_widget.setItem(2, 1, QTableWidgetItem("22")) # 第3行第2列:22
# 将表格设置为主窗口的中央控件,表格将显示在窗口中
self.setCentralWidget(self.table_widget)
# 创建应用程序对象
app = QApplication(sys.argv)
window = MainWindow()
window.show()
# 进入应用程序事件循环
sys.exit(app.exec_())
row
表示第几行,第二个参数 column
表示第几列,第三个参数 QTableWidgetItem(value)
表示你想要插入的具体数据。
QTableWidget
设置为窗口的中央控件,表格将占据窗口的主要显示区域。每个窗口只能有一个中央控件。
在实际应用中,表格中的数据通常不是手动输入的,而是从某个数据源(如列表、数据库或文件)动态获取的。接下来,我们演示如何根据一个列表动态填充表格的内容。
import sys
from PyQt5.QtWidgets import QApplication, QMainWindow, QTableWidget, QTableWidgetItem
class MainWindow(QMainWindow):
def __init__(self):
super().__init__()
self.setWindowTitle("动态填充 QTableWidget 示例")
# 数据源,包含姓名和年龄的列表
data = [
["张三", "25"],
["李四", "30"],
["王五", "22"]
]
# 根据数据源的大小动态创建表格,行数等于 data 列表的长度,列数为 2
self.table_widget = QTableWidget(len(data), 2, self)
self.table_widget.setHorizontalHeaderLabels(["姓名", "年龄"])
# 使用 for 循环填充表格
for row, (name, age) in enumerate(data):
self.table_widget.setItem(row, 0, QTableWidgetItem(name)) # 插入姓名
self.table_widget.setItem(row, 1, QTableWidgetItem(age)) # 插入年龄
# 设置表格为窗口的中央控件
self.setCentralWidget(self.table_widget)
# 创建应用程序对象
app = QApplication(sys.argv)
window = MainWindow()
window.show()
sys.exit(app.exec_())
data
是一个列表,每个子列表包含一个人的姓名和年龄。在实际应用中,数据源可能来自数据库、文件或外部 API,这里我们使用静态列表作为示例。
len(data)
决定的,列数固定为 2(姓名和年龄)。这意味着如果数据源包含更多条记录,表格会自动根据数据源的大小调整行数。
for
循环遍历数据源,enumerate
返回每条记录的索引(row
)和数据(name
和 age
)。通过 setItem()
方法,我们将每条记录中的姓名和年龄填充到相应的行和列中。
在处理大量数据时,pandas 是一个非常强大的库。它能够快速、轻松地读取 CSV 文件、Excel 文件,甚至数据库中的数据,并以 DataFrame 的形式进行操作。接下来,我们演示如何使用 pandas 读取数据,并将其展示在 QTableWidget 中。
import sys
import pandas as pd # 导入 pandas 库
from PyQt5.QtWidgets import QApplication, QMainWindow, QTableWidget, QTableWidgetItem
class MainWindow(QMainWindow):
def __init__(self):
super().__init__()
self.setWindowTitle("使用 pandas 填充 QTableWidget")
# 模拟读取的数据,通常可以通过 pd.read_csv() 或 pd.read_excel() 读取外部文件
data_frame = pd.DataFrame({
'姓名': ['张三', '李四', '王五'],
'年龄': [25, 30, 22]
})
# 根据 pandas DataFrame 的大小创建表格
self.table_widget = QTableWidget(data_frame.shape[0], data_frame.shape[1], self)
self.table_widget.setHorizontalHeaderLabels(data_frame.columns)
# 填充表格
for row in range(data_frame.shape[0]):
for col in range(data_frame.shape[1]):
self.table_widget.setItem(row, col, QTableWidgetItem(str(data_frame.iat[row, col])))
# 设置表格为中央控件
self.setCentralWidget(self.table_widget)
# 创建应用程序对象
app = QApplication(sys.argv)
window = MainWindow()
window.show()
sys.exit(app.exec_())
DataFrame
,它包含了姓名和年龄的两列。在实际应用中,你可以通过 pd.read_csv()
、pd.read_excel()
或者数据库查询来获取数据。
shape
是 pandas 的一个属性,返回 DataFrame 的形状(即行数和列数)。我们通过 shape
来动态决定表格的行数和列数。
iat
是 pandas 提供的一个方法,允许我们根据行号和列号来访问 DataFrame 中的某个具体值。通过这个方法,我们可以轻松将 DataFrame 中的每个单元格数据填充到 QTableWidget 中。
实际应用中,数据通常来自外部文件,如 CSV 文件。接下来我们将展示如何通过 QFileDialog
选择一个 CSV 文件,并使用 pandas 读取文件内容,最后将其展示在 QTableWidget
中。
import sys
import pandas as pd
from PyQt5.QtWidgets import QApplication, QMainWindow, QTableWidget, QTableWidgetItem, QFileDialog, QPushButton
class MainWindow(QMainWindow):
def __init__(self):
super().__init__()
self.setWindowTitle("从 CSV 文件填充 QTableWidget")
# 创建按钮,用于选择 CSV 文件
self.button = QPushButton("选择 CSV 文件", self)
self.button.clicked.connect(self.open_file)
# 设置按钮为中央控件
self.setCentralWidget(self.button)
def open_file(self):
# 打开文件对话框,选择 CSV 文件
file_name, _ = QFileDialog.getOpenFileName(self, "选择文件", "", "CSV 文件 (*.csv);;所有文件 (*)")
if file_name:
# 使用 pandas 读取 CSV 文件
data_frame = pd.read_csv(file_name)
# 创建表格,行数和列数由 DataFrame 决定
self.table_widget = QTableWidget(data_frame.shape[0], data_frame.shape[1], self)
self.table_widget.setHorizontalHeaderLabels(data_frame.columns)
# 填充表格
for row in range(data_frame.shape[0]):
for col in range(data_frame.shape[1]):
self.table_widget.setItem(row, col, QTableWidgetItem(str(data_frame.iat[row, col])))
# 将表格设置为中央控件
self.setCentralWidget(self.table_widget)
# 创建应用程序对象
app = QApplication(sys.argv)
window = MainWindow()
window.show()
sys.exit(app.exec_())
file_name
是用户选择的文件路径。
iat
方法按行列索引获取 DataFrame 中的具体数据,并填充到 QTableWidget 的对应单元格中。
在这一部分中,我们学习了如何使用 QTableWidget 来展示表格数据,并结合 pandas 来处理和展示从外部文件读取的数据。通过 pandas 的强大数据处理能力和 QTableWidget 的可视化展示功能,我们可以轻松将数据展示在应用程序中。
关键点:
在第4至第6部分中,我们深入讲解了 PyQt5 的信号与槽机制,展示了如何通过信号和槽处理用户操作事件,如按钮点击和文本输入。同时,我们介绍了 QFileDialog
控件,帮助用户与文件系统交互,进行文件的打开和保存操作。随后,我们重点讲解了 QTableWidget 控件及其与 pandas 的结合,展示了如何动态地从 CSV 文件或其他数据源加载并展示结构化数据。
以上就是关于【Python篇】PyQt5 超详细入门级教程(中篇一))的内容啦,各位大佬有什么问题欢迎在评论区指正,您的支持是我创作的最大动力!❤️