PyQt常用控件的使用:QFileDialog、QMessageBox、QTreeWidget、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)

部分函数默认自带参数,如果要额外带些参数,编写方式如下

python 复制代码
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:用户选择的过滤器

python 复制代码
from PyQt5.QtWidgets import QFileDialog

file_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:用户选择的过滤器

python 复制代码
from PyQt5.QtWidgets import QFileDialog

save_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, "选择目录", "")

python 复制代码
from PyQt5.QtWidgets import QFileDialog

file_path = QFileDialog.getExistingDirectory(self, 'Open File', 'E:/Code')
if file_path:
    self.edit.setText(file_path)

三、QMessageBox(对话框)

QMessageBox:是PyQt/PySide中用于显示消息对话框的类,可以用来显示信息、警告、错误或提问。以下是QMessageBox的详细使用方法

QMessageBox常规用法:

python 复制代码
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
python 复制代码
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 树结构的初始化

python 复制代码
# 创建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 递归读取完整树结构

python 复制代码
# 创建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() 勾选状态变化事件

单击事件

python 复制代码
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)

双击事件

python 复制代码
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)

勾选状态事件

python 复制代码
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)} 取消选中")

右击菜单栏

如实现右击弹出菜单栏,将当前选选项移除

python 复制代码
# 右击绑定事件
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进行部分函数封装改写,忽略右击对菜单栏选项操作

python 复制代码
class MyMenu(QtWidgets.QMenu):
    # 忽略右击选项
    def mousePressEvent(self, event):
        if event.button() == QtCore.Qt.LeftButton:
            super().mousePressEvent(event)
        else:
            event.ignore()

五、QCombox改写下拉多勾选框

一般来说QCombox只支持下拉选择一项选择,这里继承QCombox类,并对其封装改写,实现下拉多选框,即:可以选择多个选项,代码如下(这里添加了一个全选选项,需要放在开头)

python 复制代码
from PyQt5.QtWidgets import QComboBox
from PyQt5.QtCore import Qt, QEvent
from PyQt5.QtGui import QFontMetrics, QStandardItem


class 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 False
        if 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 True
                self.model().item(0).setCheckState(Qt.Checked)
                return True
        return False

    def 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中常用的单选按钮控件,用于让用户在多个互斥选项中选择一个

(注:下方省略了将按钮放入布局中)

创建单选按钮并绑定信号

python 复制代码
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被选中")

创建两组单选按钮组

python 复制代码
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} 的按钮")

# 单个按钮事件绑定同上,略
相关推荐
luojiaao10 分钟前
【Python工具开发】k3q_arxml 简单但是非常好用的arxml编辑器,可以称为arxml杀手包
开发语言·python·编辑器
终焉代码10 分钟前
STL解析——list的使用
开发语言·c++
SoFlu软件机器人13 分钟前
智能生成完整 Java 后端架构,告别手动编写 ControllerServiceDao
java·开发语言·架构
英英_20 分钟前
视频爬虫的Python库
开发语言·python·音视频
猛犸MAMMOTH25 分钟前
Python打卡第46天
开发语言·python·机器学习
多多*1 小时前
微服务网关SpringCloudGateway+SaToken鉴权
linux·开发语言·redis·python·sql·log4j·bootstrap
梓仁沐白1 小时前
【Kotlin】协程
开发语言·python·kotlin
Java Fans1 小时前
在WPF项目中集成Python:Python.NET深度实战指南
python·.net·wpf
Cyanto1 小时前
Java并发编程面试题
java·开发语言·面试
海的诗篇_1 小时前
前端开发面试题总结-JavaScript篇(一)
开发语言·前端·javascript·学习·面试