PyQt常用控件的使用:QFileDialog、QMessageBox、QTreeWidget、QRadioButton等
文章目录
- 一、控件常用函数介绍
- 二、QFileDialog(文件类操作)
- 三、QMessageBox(对话框)
- 四、QTreeWidget(树结构类操作)
- 4.1 树结构的初始化
- 4.2 递归读取完整树结构
- 4.3 信号槽绑定
- 五、QCombox改写下拉多勾选框
- 六、QRadioButton(单选按钮控件)
一、控件常用函数介绍
常用函数
函数 | 功能 |
---|---|
setText(txt) | 设置内容 |
text() | 获取内容 |
setEnabled(bool) | 使按钮失效 |
setCheckable(bool) | 打开开关状态 |
setChecked(bool) | 设置按钮状态 (如果是按钮需要先设置setCheckable状态) |
isChecked() | 获取按钮状态 (如果是按钮则需要先设置setCheckable状态) |
setIcon(QIcon(QPixmap(“icon.jpg”))) | 设置图标 |
setIconSizeQSize(100, 100) | 设置图标的大小 |
setShortcut(“Alt+O”) | 设置快捷键 |
setStyleSheet(“x:x;x:x;”) | 设置样式(CSS) |
setToolTip(text) | 设置气泡(悬停提示) |
常见事件绑定函数
函数 | 功能 |
---|---|
clicked.connect() | 按钮单击(QPushButton, QRadioButton) |
currentIndexChanged.connect() | 下拉框内容变化(QComboBox) |
triggered.connect() | 菜单键点击(QAction) |
setContextMenuPolicy(QtCore.Qt.CustomContextMenu) customContextMenuRequested.connect() | 选项右击(QTreeWidget,自带参数pos) |
部分函数默认自带参数,如果要额外带些参数,编写方式如下
self.tree_widget.setContextMenuPolicy(QtCore.Qt.CustomContextMenu)
self.tree_widget.customContextMenuRequested.connect(lambda pos: self.right_clicked_tree(pos, "abc"))# pos为自带参数,txt为自定义参数
def right_clicked_tree(self, pos, txt):pass
二、QFileDialog(文件类操作)
QFileDialog:是 PyQt/PySide 中用于文件选择的标准对话框组件,它提供了打开/保存文件、选择目录等功能接口
选择创建文件。
获取文件路径
file_path, selected_filter = QFileDialog.getOpenFileName(parent=None, caption='', directory='', filter='',options=QFileDialog.Options())
参数:
parent:QWidget 父窗口,通常传入 self 或 None
caption:对话框标题
directory:初始显示目录(空字符串表示当前目录)
filter:文件类型过滤器
options:额外选项配置
返回值:
file_path:用户选择的文件路径(字符串),如果取消则为空字符串
selected_filter:用户选择的过滤器
from PyQt5.QtWidgets import QFileDialogfile_path, _ = QFileDialog.getOpenFileName(self, 'Open File', 'E:/Code', 'Text Files(*.txt *.csv);;All Files(*)')
if file_path:print("选择的文件:", file_path)
获取保存文件路径
file_path, selected_filter = QFileDialog.getSaveFileName(parent=None, caption='', directory='', filter='', options=QFileDialog.Options())
参数:
parent:QWidget 父窗口,通常传入 self 或 None
caption:对话框标题
directory:初始显示目录(空字符串表示当前目录)
filter:文件类型过滤器
options:额外选项配置
返回值:
file_path:指定的保存路径(字符串),如果取消则为空字符串
selected_filter:用户选择的过滤器
from PyQt5.QtWidgets import QFileDialogsave_path, filter_used = QFileDialog.getSaveFileName(None,"导出数据","data_export","CSV文件 (*.csv);;JSON文件 (*.json)")
if save_path:pass
获取文件夹路径
directory = QFileDialog.getExistingDirectory(parent=None, caption='', directory='', options=QFileDialog.Options())
参数:
parent:QWidget 父窗口,通常传入 self 或 None
caption:对话框标题
directory:初始显示目录(空字符串表示当前目录)
options:额外选项配置
返回值:
file_path:选择的目录路径(字符串),如果取消则为空字符串
dir_path = QFileDialog.getExistingDirectory( None, “选择目录”, “”)
from PyQt5.QtWidgets import QFileDialogfile_path = QFileDialog.getExistingDirectory(self, 'Open File', 'E:/Code')
if file_path:self.edit.setText(file_path)
三、QMessageBox(对话框)
QMessageBox:是PyQt/PySide中用于显示消息对话框的类,可以用来显示信息、警告、错误或提问。以下是QMessageBox的详细使用方法
QMessageBox常规用法:
from PyQt5.QtWidgets import QMessageBox# 显示一个简单的信息对话框
QMessageBox.information(None, "标题", "这是一条信息消息") # None可以是QWidget 父窗口 即QWidget窗口时使用self# 显示警告对话框
QMessageBox.warning(None, "警告", "这是一个警告消息")# 显示错误对话框
QMessageBox.critical(None, "错误", "这是一个错误消息")# 显示提问对话框(最后一个参数为默认选项)
reply = QMessageBox.question(None, "问题", "你确定要继续吗?", QMessageBox.Yes | QMessageBox.No, QMessageBox.No)
if reply == QMessageBox.Yes:print("用户选择了是")
else:print("用户选择了否")
QMessageBox自定义用法:
图标类型 | 含义 |
---|---|
QMessageBox.NoIcon | 无图标 |
QMessageBox.Question | 问题图标 |
QMessageBox.Information | 信息图标 |
QMessageBox.Warning | 警告图标 |
QMessageBox.Critical | 错误图标 |
按钮类型 |
---|
QMessageBox.Ok |
QMessageBox.Open |
QMessageBox.Save |
QMessageBox.Cancel |
QMessageBox.Close |
QMessageBox.Yes |
QMessageBox.No |
QMessageBox.Abort |
QMessageBox.Retry |
QMessageBox.Ignore |
msg_box = QMessageBox()
msg_box.setIcon(QMessageBox.Information) # 设置图标类型
msg_box.setWindowTitle("自定义对话框") # 设置标题
msg_box.setText("这是主要消息") # 设置主要文本
msg_box.setInformativeText("这是附加信息") # 设置附加信息
msg_box.setDetailedText("这是详细文本\n可以有多行") # 设置详细文本# 添加自定义按钮
msg_box.addButton("自定义按钮1", QMessageBox.AcceptRole)
msg_box.addButton("自定义按钮2", QMessageBox.RejectRole)# 显示对话框
ret = msg_box.exec_()if ret == QMessageBox.AcceptRole:print("点击了自定义按钮1")
else:print("点击了其他按钮")
四、QTreeWidget(树结构类操作)
QTreeWidget:是PyQt中用于显示树形结构数据的重要组件,它继承自QTreeView,提供了更简单易用的接口来处理树状数据。常用函数如下:
函数 | 含义 |
---|---|
root_tree.setColumnCount(2) | 设置列数(两列) |
root_tree.setHeaderLabels([“名称”, “类型”]) | 设置列标题 |
root_tree.setColumnWidth(0, 200) | 设置列宽(第一列宽度200) |
root_tree.header().setSectionResizeMode(QtWidgets.QHeaderView.ResizeToContents) | 列宽自适应 |
root_tree.expandAll() | 全部展开 |
root_tree.collapseAll() | 全部收起 |
root_tree.invisibleRootItem().childCount() | 获取根节点的子节点数 |
root_tree.invisibleRootItem().child(i) | 获取根节点的某个子节点 |
item.childCount() | 获取当前节点的子节点数 |
item.child(i) | 获取当前节点的某个子节点 |
item.setText(0, “根节点”) | 设置内容 |
item.setIcon(0, QIcon(“”)) | 设置图片 |
item.setCheckState(0, QtCore.Qt.Unchecked) | 设置选中状态 |
item.checkState(0) | 获取选中状态(参数表示哪列) |
item.text(0) | 获取某列内容(参数表示哪列) |
item.parent().text(column) | 获取父节点内容(参数表示哪列) |
4.1 树结构的初始化
# 创建QTreeWidget对象
self.tree_widget = QTreeWidget()# 设置列数、列标题、列宽
self.tree_widget.setColumnCount(2)
self.tree_widget.setHeaderLabels(["名称", "类型"])
self.tree_widget.setColumnWidth(0, 200)
self.tree_widget.setColumnWidth(1, 150)
# self.tree_widget.header().setSectionResizeMode(QtWidgets.QHeaderView.ResizeToContents) # 列宽自适应# 添加数据项(父节点)
root_item = QTreeWidgetItem(self.tree_widget)
root_item.setText(0, "根节点")
root_item.setText(1, "文件夹")
root_item.setCheckState(0, QtCore.Qt.Unchecked) # 设置勾选状态(不勾选) 可省略# 添加数据项(子节点)
child_item = QTreeWidgetItem(root_item)
child_item.setText(0, "子节点1")
child_item.setText(1, "文件")
child_item.setCheckState(0, QtCore.Qt.Unchecked) # 设置勾选状态(不勾选) 可省略self.tree_widget.expandAll() # 所有节点展开
self.tree_widget.collapseAll() # 所有节点收起
4.2 递归读取完整树结构
# 创建QTreeWidget实例
tree_widget = QTreeWidget() # 初始化...略
# 获取不可见的根项
root = tree_widget.invisibleRootItem()
for i in range(root.childCount()):item = root.child(i)read_tree_item(item)def read_tree_item(item):"""递归读取树形项及其子项"""select_status = item.checkState(0) # 获取勾选状态 (参数表示列索引)# 遍历读取每列信息for col in range(item.columnCount()):print(item.text(col))# 递归处理子项for child_index in range(item.childCount()):child = item.child(child_index)read_tree_item(child)
4.3 信号槽绑定
函数 | 含义 |
---|---|
itemSelectionChanged.connect() | 项选择变化 |
itemClicked.connect() | 项被点击 |
itemDoubleClicked.connect() | 项被双击 |
itemExpanded.connect() | 项展开 |
itemCollapsed.connect() | 项折叠 |
itemChanged.connect() | 项内容编辑 |
setContextMenuPolicy(QtCore.Qt.CustomContextMenu) customContextMenuRequested.connect(self.right_clicked_tree) | 右击事件 |
itemChanged.connect() | 勾选状态变化事件 |
单击事件
self.tree_widget.itemClicked.connect(self.clicked_item)def clicked_item(self, item, column): # item: 点击项 column:列if item:# 当前节点信息item_text = item.text(column) # item.text(0)# 获取父节点信息if item.parent():parent_text = item.parent().text(column)# 获取子节点信息for child_index in range(item.childCount()):child_text = item.child(child_index).text(column)
双击事件
self.tree_widget.itemDoubleClicked.connect(self.double_clicked_item)def double_clicked_item(self, item, column): # item: 点击项 column:列if item:# 当前节点信息item_text = item.text(column) # item.text(0)# 获取父节点信息if item.parent():parent_text = item.parent().text(column)# 获取子节点信息for child_index in range(item.childCount()):child_text = item.child(child_index).text(column)
勾选状态事件
self.tree_widget.itemChanged.connect(self.item_changed)def item_changed(self, item, column): # item: 点击项 column:列if item.checkState(0) == Qt.Checked:print(f"项目 {item.text(0)} 被选中")else:print(f"项目 {item.text(0)} 取消选中")
右击菜单栏
如实现右击弹出菜单栏,将当前选选项移除
# 右击绑定事件
self.tree_widget.setContextMenuPolicy(QtCore.Qt.CustomContextMenu)
self.tree_widget.customContextMenuRequested.connect(self.right_clicked_tree)def right_clicked_tree(self, pos):item = self.tree_widget.itemAt(pos)if item:menu = QMenu(self.tree_widget)remove_item = QAction("remove", self.tree_widget)remove_item.triggered.connect(lambda: self.remove_item(item)) # 移除事件绑定menu.addAction(remove_item)menu.exec_(QtGui.QCursor.pos())# 移除当前项
def remove_item(self, item):if item.parent():item.parent().removeChild(item)else:index = self.tree_widget.indexOfTopLevelItem(item)self.tree_widget.takeTopLevelItem(index)
一般来说,直接使用Menu,对选项右击也会出发事件,这是需要对menu进行部分函数封装改写,忽略右击对菜单栏选项操作
class MyMenu(QtWidgets.QMenu):# 忽略右击选项def mousePressEvent(self, event):if event.button() == QtCore.Qt.LeftButton:super().mousePressEvent(event)else:event.ignore()
五、QCombox改写下拉多勾选框
一般来说QCombox只支持下拉选择一项选择,这里继承QCombox类,并对其封装改写,实现下拉多选框,即:可以选择多个选项,代码如下(这里添加了一个全选选项,需要放在开头)
from PyQt5.QtWidgets import QComboBox
from PyQt5.QtCore import Qt, QEvent
from PyQt5.QtGui import QFontMetrics, QStandardItemclass MyComboBox(QComboBox):def __init__(self, *args, **kwargs):super().__init__(*args, **kwargs)self.setEditable(True)self.lineEdit().setReadOnly(True)self.model().dataChanged.connect(self.updateText)self.lineEdit().installEventFilter(self)self.view().viewport().installEventFilter(self)self.updateText()def eventFilter(self, object, event):if object == self.lineEdit():if event.type() == QEvent.MouseButtonRelease:self.shwPopup()return Falseif object == self.view().viewport():if event.type() == QEvent.MouseButtonRelease:index = self.view().indexAt(event.pos())item = self.model().item(index.row())if item.text() == "ALL" and item.checkState() == Qt.Checked:[self.model().item(i).setCheckState(Qt.Unchecked) for i in range(self.model().rowCount())]elif item.text() == "ALL":[self.model().item(i).setCheckState(Qt.Checked) for i in range(self.model().rowCount())]else:item.setCheckState(Qt.Unchecked if item.checkState() == Qt.Checked else Qt.Checked)self.model().item(0).setCheckState(Qt.Unchecked)for i in range(1, self.model().rowCount()):if self.model().item(i).checkState() != Qt.Checked:self.model().item(i).setCheckState(Qt.Unchecked)return Trueself.model().item(0).setCheckState(Qt.Checked)return Truereturn Falsedef updateText(self):text = ".".join([self.model().item(i).text() for i in range(self.model().rowCount())if self.model().item(i).checkState() == Qt.Checked])elidedText = QFontMetrics(self.lineEdit().font()).elidedText(text, Qt.ElideRight, self.lineEdit().width())self.lineEdit().setText(elidedText)def addItem(self, text, data=None):item = QStandardItem()item.setText(text)item.setFlags(Qt.ItemIsEnabled|Qt.ItemIsUserCheckable)item.setData(Qt.Unchecked, Qt.CheckStateRole)self.model().appendRow(item)self.lineEdit().setText("")def currentText(self):res = [self.model().item(i).text() for i in range(self.model().rowCount())if self.model().item(i).checkState() == Qt.Checked]return res
六、QRadioButton(单选按钮控件)
QRadioButton是PyQt中常用的单选按钮控件,用于让用户在多个互斥选项中选择一个
(注:下方省略了将按钮放入布局中)
创建单选按钮并绑定信号
from PyQt5.QtWidgets import QRadioButton# 创建单选按钮
radio1 = QRadioButton("选项1")
radio2 = QRadioButton("选项2")# 设置默认选中
radio1.setChecked(True)# 信号绑定
radio1.clicked.connect(self.on_radio_clicked)
radio2.clicked.connect(self.on_radio_clicked)
def on_radio_clicked(self):if radio1.isChecked():print("选项1被选中")elif radio2.isChecked():print("选项2被选中")
创建两组单选按钮组
from PyQt5.QtWidgets import QButtonGroup# 创建按钮组一:二选一
button_group1 = QButtonGroup()
radio1 = QRadioButton("选项1")
button_group.addButton(radio1)
radio2 = QRadioButton("选项2")
button_group.addButton(radio2)
radio1.setChecked(True) # 默认选中# 创建按钮组二:二选一
button_group2 = QButtonGroup()
radio3 = QRadioButton("选项3")
button_group2.addButton(radio3, 3)
radio4 = QRadioButton("选项4")
button_group2.addButton(radio4, 4)
radio3.setChecked(True) # 默认选中# 按钮组事件绑定
button_group1.buttonClicked.connect(self.on_radio_group_clicked)
def on_radio_group_clicked(self, button):print(f"选中了: {button.text()}")# id识别按钮 绑定按钮组的idClicked信号
button_group.idClicked.connect(self.on_radio_group_id_clicked)
def on_radio_group_id_clicked(self, id):print(f"选中了ID为 {id} 的按钮")# 单个按钮事件绑定同上,略