一、按钮
1 QPushButton :按钮
QPushButton 就是常见的按钮
官网介绍
(1) 信号:被点击
当按钮被点击就会发出 clicked 信号,可以这样指定处理该信号的函数
button.clicked.connect(handleCalc)
(2) 改变文本
代码中可以使用 setText 方法来改变按钮文本,比如
button.setText(text)
(3) 禁用、启用
所有控件(继承自QWidget类)都支持 禁用和启用方法。
禁用后,该控件不再处理用户操作
- 禁用
button.setEnabled(False)
- 启用
button.setEnabled(True)
(4) 设置图标
可以通过如下方法给按钮设置图标
from PySide6.QtCore import Qt,QSize
from PySide6.QtGui import QIcon
# 设置图标
button.setIcon(QIcon('logo.png'))
# 设置图标大小
button.setIconSize(QSize(30, 30))
2 单选按钮和按钮组
(1)说明
QRadioButton 是单选按钮,如图所示
【注】:
同一个父窗口 里面的多个单选按钮,只能选中一项。
如果你有多组单选按钮, 每组都应该有不同的父控件,或者不同的Layout。
通常建议:多组单选按钮,放到不同的 按钮组 QButtonGroup 中
(2)信号:选中状态改变(搭配按钮组使用)
如果用户操作点击了按钮组 QButtonGroup 中的一个按钮, QButtonGroup 就会发出 buttonClicked 信号,可以这样指定处理该信号的函数
buttongroup.buttonClicked.connect(handleButtonClicked)
然后,在处理函数中调用QButtonGroup对象的 checkedButton() 函数,返回值就是被选中的按钮对象。
再调用这个返回的按钮对象的 text() 方法得到界面文本,就可以知道是哪个选项被选中了。
3 多选按钮和按钮组
二、标签:QLabel
QLabel 就是常见的标签,可以用来显示文字(包括纯文本和富文本)、图片 甚至动画。
三、编辑框
1 单行文本框
2 多行文本框
3 文本浏览框(只能展示文本不能修改输入文本)
三、下拉框
四、表格:QTableWidget
QTableWidget 是表格控件,如下图所示
表格控件单元格里面可以显示文字,也可以显示富文本、图片等内容。
表格控件的每个单元格里面要显示内容,都必须创建一个 QTableWidgetItem 类型的对象。
也就是说,我们如果要往表格的单元格里面添加东西,都必须QTableWidgetItem 类型的对象,往这个里面添加东西。
Qt Designer 如下图 选择:
1 实例化(如果不采用ui,也可以代码生成)
可以通过Qt设计师创建UI,然后加载界面的方式实例化。
也可以直接通过代码创建表格控件实例
from PySide6 import QtWidgets
rows = 0 # 行数
columns = 2 # 列数
# parent变量对应的是父控件对象
table = QtWidgets.QTableWidget(rows, columns, parent)
2 设置表格自动缩放(一定要设置,不然很难看)
# 设置表格自动缩放(放在最前面)
table.horizontalHeader().setStretchLastSection(True)
3 设置表格不可编辑
# 设置表格不可编辑
table.setEditTriggers(QTableWidget.NoEditTriggers)
4 设置表格列数并添加表头、设置表格行数
# 设置表格列数 2列
table.setColumnCount(2)
# 添加表头
table.setHorizontalHeaderLabels(["名称", "值"])
# 设置表格行数 10行
table.setRowCount(10)
5 插入一行、删除一行
【注】:index是从零开始的
- insertRow 方法可以在指定位置插入一行,比如
table.insertRow(0)
# 就插入一行到第 1 行这个位置, 表格原来第1行(包括原来的第1行)以后的内容,全部往下移动一行。
table.insertRow(2)
# 就插入一行到第 3 行这个位置, 表格原来第3行(包括原来的第3行)以后的内容,全部往下移动一行。
- removeRow 方法可以删除指定位置的一行,比如
table.removeRow(2)
# 就删除第 3 行, 表格原来第3行以后的内容,全部往上移动一行。
6 设置单元格内容、对齐、属性
(1)指定位置单元格添加内容和修改指定位置单元格内容
【注】:index是从零开始的
qt表格的单元格内的内容对象 是一个 单元格对象 QTableWidgetItem 实例
- 如果单元格 没有被设置过内容,我们需要先为这个单元格创建QTableWidgetItem 对象,可以这样
from PySide6.QtWidgets import QTableWidgetItem
item = QTableWidgetItem()
item.setText('白月黑羽')
table.setItem(row_index, column_index, item)
# table.setItem(0, 0, QTableWidgetItem('白月黑羽')) 就是将第一列设置内容为'白月黑羽'。这种简写方式也是可以的
- 如果单元格 已经被设置过文本内容,我们就不必额外创建QTableWidgetItem 对象了
item 方法可以获取指定位置的 QTableWidgetItem ,再调用这个对象的 setText 方法,就可以设置单元格文本内容,比如
table.item(2,4).setText('白月黑羽-江老师')
# 就设置了 第3行,第5列 的单元格里面的文本。
(2)设置指定位置单元格为只读
- 如果希望某个单元格为 只读,不允许修改,可以使用QTableWidgetItem对象的 setFlags 方法,像这样
from PySide6.QtWidgets import QTableWidgetItem
from PySide6.QtCore import Qt
item = QTableWidgetItem('白月黑羽')
item.setFlags(Qt.ItemIsEnabled) # 参数名字段不允许修改
table.setItem(row_index, column_index, item)
(3)设置指定单元格文本内容居中对齐
- 如果想文本内容 居中对齐,每个当对应的QTableWidgetItem 调用 setTextAlignment,如下
from PySide6.QtWidgets import QTableWidgetItem
from PySide6.QtCore import Qt
item = QTableWidgetItem()
item.setText('白月黑羽')
# 文本居中
item.setTextAlignment(Qt.AlignCenter)
table.setItem(row_index, column_index, item)
7 获取内容
(1)获取指定单元格的文本内容
item 方法可以指定位置的单元格对象(QTableWidgetItem) ,再调用这个对象的 text 方法,就可以获取文本内容,比如
table.item(2,4).text()
# 获取了 第3行,第5列 的单元格里面的文本。
(2)获取所有行数、列数
代码中可以使用 rowCount 方法来获取表格所有的 行数 ,比如
rowcount = table.rowCount()
可以使用 columnCount 方法来获取表格所有的 列数 ,比如
rowcount = table.columnCount()
(3)获取表格当前选中的行数或者列数
获取当前选中的单行或者单列
代码中可以使用 currentRow 方法来获取当前选中是第几行,比如
currentrow = table.currentRow()
【注】:如果没有选中行,这里返回的是 -1
注意:行数是从0开始的, 第一行的行数是 0
以上代码显然需要搭配按钮世界一起来演示,下面是示例
import sys
from PyQt5.QtWidgets import QApplication, QTableWidget, QTableWidgetItem, QVBoxLayout, QPushButton, QWidget, QMessageBox
class MyWindow(QWidget):
def __init__(self):
super().__init__()
# 创建QTableWidget
self.tableWidget = QTableWidget(5, 3) # 5行3列
self.tableWidget.setItem(0, 0, QTableWidgetItem("Item 1"))
self.tableWidget.setItem(1, 0, QTableWidgetItem("Item 2"))
self.tableWidget.setItem(2, 0, QTableWidgetItem("Item 3"))
# 创建按钮
self.button = QPushButton("Get Current Row")
self.button.clicked.connect(self.get_current_row)
# 布局设置
layout = QVBoxLayout()
layout.addWidget(self.tableWidget)
layout.addWidget(self.button)
self.setLayout(layout)
self.setWindowTitle("Get Current Row Example")
self.resize(400, 300)
def get_current_row(self):
current_row = self.tableWidget.currentRow() # 获取当前行
if current_row >= 0: # 确保有选中的行
item_text = self.tableWidget.item(current_row, 0).text() # 获取当前行第一列的文本
QMessageBox.information(self, "Current Row", f"Current Row: {current_row}, Item: {item_text}")
else:
QMessageBox.warning(self, "Warning", "No row selected!")
if __name__ == "__main__":
app = QApplication(sys.argv)
window = MyWindow()
window.show()
sys.exit(app.exec_())
获取当前选中的多行或者多列
QTableWidget支持多行选择。你可以通过设置选择行为来实现这一点,并使用selectedItems()方法获取所有选中的项。下面是一个示例代码,展示如何获取所有选中的行:
import sys
from PyQt5.QtWidgets import QApplication, QTableWidget, QTableWidgetItem, QVBoxLayout, QPushButton, QWidget, QMessageBox
class MyWindow(QWidget):
def __init__(self):
super().__init__()
# 创建QTableWidget
self.tableWidget = QTableWidget(5, 3) # 5行3列
for i in range(5):
self.tableWidget.setItem(i, 0, QTableWidgetItem(f"Item {i + 1}"))
# 设置多行选择
self.tableWidget.setSelectionMode(QTableWidget.MultiSelection)
# 创建按钮
self.button = QPushButton("Get Selected Rows")
self.button.clicked.connect(self.get_selected_rows)
# 布局设置
layout = QVBoxLayout()
layout.addWidget(self.tableWidget)
layout.addWidget(self.button)
self.setLayout(layout)
self.setWindowTitle("Get Selected Rows Example")
self.resize(400, 300)
def get_selected_rows(self):
selected_items = self.tableWidget.selectedItems() # 获取所有选中的项
if selected_items:
selected_rows = {item.row() for item in selected_items} # 这里做一个去重
selected_info = "\n".join(f"Row: {row}, Item: {self.tableWidget.item(row, 0).text()}" for row in selected_rows)
QMessageBox.information(self, "Selected Rows", selected_info)
else:
QMessageBox.warning(self, "Warning", "No rows selected!")
if __name__ == "__main__":
app = QApplication(sys.argv)
window = MyWindow()
window.show()
sys.exit(app.exec_())
【注】:为什么专门演示这个功能呢?因为这个可以制作选中的行的表格数据进行导出这种功能。
8 清空/删除表格所有内容
- clearContents 方法可以清除表格所有的内容,比如
table.clearContents()
清除后,仍然会留下表格栏
如果连表格栏都要删除,可以使用 setRowCount(0),像这样
table.setRowCount(0)
9 设置 表格框 和 单元格边线 的颜色,可以使用样式如下
一般这种css放在本地我们在读进来即可:
QTableWidget {
border:1px solid green;
gridline-color: rgb(71, 191, 255);
}
变成代码如下:
table.setStyleSheet("QTableWidget { border: 1px solid green; gridline-color: rgb(71, 191, 255); }")
10 信号:单元格内容改动触发事件
当用户修改了一个单元格的内容,会发出 cellChanged 信号,并且携带参数指明该单元格的行号和列号。
我们的代码可以对该信号进行相应的处理。
示例代码如下
def __init__(self):
# 指定单元格改动信号处理函数
self.ui.table.cellChanged.connect(self.cfgItemChanged)
def cfgItemChanged(self,row,column):
# 获取更改内容
cfgName = self.ui.table.item(row, 0).text() # 首列为配置名称
cfgValue = self.ui.table.item(row, column).text()
五、树
六、消息框
综合练习
pyuic生成的ui代码(不需要我们自己写):
# -*- coding: utf-8 -*-
# Form implementation generated from reading ui file 'mainWindow_ui.ui'
#
# Created by: PyQt5 UI code generator 5.15.9
#
# WARNING: Any manual changes made to this file will be lost when pyuic5 is
# run again. Do not edit this file unless you know what you are doing.
from PyQt5 import QtCore, QtGui, QtWidgets
class Ui_MainWindow(object):
def setupUi(self, MainWindow):
MainWindow.setObjectName("MainWindow")
MainWindow.resize(830, 730)
self.centralwidget = QtWidgets.QWidget(MainWindow)
self.centralwidget.setObjectName("centralwidget")
self.verticalLayout_4 = QtWidgets.QVBoxLayout(self.centralwidget)
self.verticalLayout_4.setObjectName("verticalLayout_4")
self.verticalLayout_3 = QtWidgets.QVBoxLayout()
self.verticalLayout_3.setObjectName("verticalLayout_3")
self.horizontalLayout = QtWidgets.QHBoxLayout()
self.horizontalLayout.setObjectName("horizontalLayout")
self.comboBox = QtWidgets.QComboBox(self.centralwidget)
self.comboBox.setObjectName("comboBox")
self.horizontalLayout.addWidget(self.comboBox)
self.lineEdit = QtWidgets.QLineEdit(self.centralwidget)
self.lineEdit.setObjectName("lineEdit")
self.horizontalLayout.addWidget(self.lineEdit)
self.send_button = QtWidgets.QPushButton(self.centralwidget)
self.send_button.setObjectName("send_button")
self.horizontalLayout.addWidget(self.send_button)
self.verticalLayout_3.addLayout(self.horizontalLayout)
self.line_3 = QtWidgets.QFrame(self.centralwidget)
self.line_3.setFrameShape(QtWidgets.QFrame.HLine)
self.line_3.setFrameShadow(QtWidgets.QFrame.Sunken)
self.line_3.setObjectName("line_3")
self.verticalLayout_3.addWidget(self.line_3)
self.horizontalLayout_4 = QtWidgets.QHBoxLayout()
self.horizontalLayout_4.setObjectName("horizontalLayout_4")
self.verticalLayout = QtWidgets.QVBoxLayout()
self.verticalLayout.setObjectName("verticalLayout")
self.horizontalLayout_2 = QtWidgets.QHBoxLayout()
self.horizontalLayout_2.setObjectName("horizontalLayout_2")
self.label = QtWidgets.QLabel(self.centralwidget)
self.label.setObjectName("label")
self.horizontalLayout_2.addWidget(self.label)
self.add_button = QtWidgets.QPushButton(self.centralwidget)
self.add_button.setObjectName("add_button")
self.horizontalLayout_2.addWidget(self.add_button)
self.decrease_button = QtWidgets.QPushButton(self.centralwidget)
self.decrease_button.setObjectName("decrease_button")
self.horizontalLayout_2.addWidget(self.decrease_button)
self.verticalLayout.addLayout(self.horizontalLayout_2)
self.tableWidget = QtWidgets.QTableWidget(self.centralwidget)
self.tableWidget.setObjectName("tableWidget")
self.tableWidget.setColumnCount(0)
self.tableWidget.setRowCount(0)
self.verticalLayout.addWidget(self.tableWidget)
self.horizontalLayout_4.addLayout(self.verticalLayout)
self.line = QtWidgets.QFrame(self.centralwidget)
self.line.setFrameShape(QtWidgets.QFrame.VLine)
self.line.setFrameShadow(QtWidgets.QFrame.Sunken)
self.line.setObjectName("line")
self.horizontalLayout_4.addWidget(self.line)
self.verticalLayout_2 = QtWidgets.QVBoxLayout()
self.verticalLayout_2.setObjectName("verticalLayout_2")
self.horizontalLayout_3 = QtWidgets.QHBoxLayout()
self.horizontalLayout_3.setObjectName("horizontalLayout_3")
spacerItem = QtWidgets.QSpacerItem(40, 20, QtWidgets.QSizePolicy.Expanding, QtWidgets.QSizePolicy.Minimum)
self.horizontalLayout_3.addItem(spacerItem)
self.label_2 = QtWidgets.QLabel(self.centralwidget)
self.label_2.setObjectName("label_2")
self.horizontalLayout_3.addWidget(self.label_2)
spacerItem1 = QtWidgets.QSpacerItem(40, 20, QtWidgets.QSizePolicy.Expanding, QtWidgets.QSizePolicy.Minimum)
self.horizontalLayout_3.addItem(spacerItem1)
self.verticalLayout_2.addLayout(self.horizontalLayout_3)
self.textEdit = QtWidgets.QTextEdit(self.centralwidget)
self.textEdit.setObjectName("textEdit")
self.verticalLayout_2.addWidget(self.textEdit)
self.horizontalLayout_4.addLayout(self.verticalLayout_2)
self.verticalLayout_3.addLayout(self.horizontalLayout_4)
self.line_2 = QtWidgets.QFrame(self.centralwidget)
self.line_2.setFrameShape(QtWidgets.QFrame.HLine)
self.line_2.setFrameShadow(QtWidgets.QFrame.Sunken)
self.line_2.setObjectName("line_2")
self.verticalLayout_3.addWidget(self.line_2)
self.textBrowser = QtWidgets.QTextBrowser(self.centralwidget)
self.textBrowser.setObjectName("textBrowser")
self.verticalLayout_3.addWidget(self.textBrowser)
self.verticalLayout_4.addLayout(self.verticalLayout_3)
self.horizontalLayout_5 = QtWidgets.QHBoxLayout()
self.horizontalLayout_5.setObjectName("horizontalLayout_5")
spacerItem2 = QtWidgets.QSpacerItem(40, 20, QtWidgets.QSizePolicy.Expanding, QtWidgets.QSizePolicy.Minimum)
self.horizontalLayout_5.addItem(spacerItem2)
self.clear_button = QtWidgets.QPushButton(self.centralwidget)
self.clear_button.setObjectName("clear_button")
self.horizontalLayout_5.addWidget(self.clear_button)
spacerItem3 = QtWidgets.QSpacerItem(40, 20, QtWidgets.QSizePolicy.Expanding, QtWidgets.QSizePolicy.Minimum)
self.horizontalLayout_5.addItem(spacerItem3)
self.verticalLayout_4.addLayout(self.horizontalLayout_5)
MainWindow.setCentralWidget(self.centralwidget)
self.menubar = QtWidgets.QMenuBar(MainWindow)
self.menubar.setGeometry(QtCore.QRect(0, 0, 830, 23))
self.menubar.setObjectName("menubar")
MainWindow.setMenuBar(self.menubar)
self.statusbar = QtWidgets.QStatusBar(MainWindow)
self.statusbar.setObjectName("statusbar")
MainWindow.setStatusBar(self.statusbar)
self.retranslateUi(MainWindow)
QtCore.QMetaObject.connectSlotsByName(MainWindow)
def retranslateUi(self, MainWindow):
_translate = QtCore.QCoreApplication.translate
MainWindow.setWindowTitle(_translate("MainWindow", "MainWindow"))
self.send_button.setText(_translate("MainWindow", "发送"))
self.label.setText(_translate("MainWindow", " 消息头"))
self.add_button.setText(_translate("MainWindow", "+"))
self.decrease_button.setText(_translate("MainWindow", "-"))
self.label_2.setText(_translate("MainWindow", " 消息体"))
self.clear_button.setText(_translate("MainWindow", "清除"))
界面逻辑代码
# !/usr/bin/env python
# _*_coding: utf-8 _*_
# @Time : 2024/9/22 22:33
# @Author : JU HE
# @Version: V0.1
# @File : mainWindow.py
# @Email : 13966915864@163.com
# @desc : 添加描述
import sys
import requests
from mainWindow_ui import Ui_MainWindow
from PyQt5.QtWidgets import (QApplication, QHeaderView,
QMainWindow,
QComboBox,QLineEdit,QPushButton,QVBoxLayout,QHBoxLayout,QLabel,QTableWidget,QTableWidgetItem,QFrame)
class mainWindow(QMainWindow):
def __init__(self):
super().__init__()
self.ui = Ui_MainWindow()
self.ui.setupUi(self)
# 下拉框添加选择列表项
self.ui.comboBox.addItems(["GET","POST", "PUT", "DELETE"])
# 设置表格自动缩放
self.ui.tableWidget.horizontalHeader().setStretchLastSection(True)
# self.ui.tableWidget.setStyleSheet("QTableWidget { border: 1px solid green; gridline-color: rgb(71, 191, 255); }")
# 设置表格列数 2列
self.ui.tableWidget.setColumnCount(2)
# 添加表头
self.ui.tableWidget.setHorizontalHeaderLabels(["名称", "值"])
# add_button和decrease_button按钮绑定点击事件
self.ui.add_button.clicked.connect(self.add_button_clicked)
self.ui.decrease_button.clicked.connect(self.decrease_button_clicked)
# send_button按钮绑定点击事件
self.ui.send_button.clicked.connect(self.send_button_clicked)
# clear_button按钮绑定点击事件
self.ui.clear_button.clicked.connect(self.clear_button_clicked)
def add_button_clicked(self):
'''表格末尾添加一行'''
# 获取当前表格的所有行数
row_count = self.ui.tableWidget.rowCount()
self.ui.tableWidget.insertRow(row_count)
def decrease_button_clicked(self):
'''删除表格选中的行'''
# 获取当前选中的行
row = self.ui.tableWidget.currentRow()
print(row)
# 如果没有选中行,row=-1
if row != -1:
self.ui.tableWidget.removeRow(row)
def send_button_clicked(self):
# 下拉框选择的请求方法
method = self.ui.comboBox.currentText()
# 单行文本框输入的url
url = self.ui.lineEdit.text()
# 请求的消息体
payload = self.ui.textEdit.toPlainText()
# 获取表格里面的消息头,放在一个字典
headers = {}
for row in range(self.ui.tableWidget.rowCount()):
key = self.ui.tableWidget.item(row, 0).text()
value = self.ui.tableWidget.item(row, 1).text()
headers[key] = value
# 这里的 requests 请求,不明白没有关系,我们的目标是将这个请求发送出去,然后得到响应,并将响应显示在textBrowser中
try:
req = requests.Request(method, url, headers=headers, data=payload)
prepped = req.prepare()
s = requests.Session()
resp = s.send(prepped)
join = "\n".join([f"{k}: {v}" for k, v in resp.headers.items()])
self.ui.textBrowser.append(
f"\n\n--------------------->得到响应<---------------------\nHTTP/1.1 {resp.status_code}\n {join}\n\n{resp.text}")
except Exception as e:
self.ui.textBrowser.append(f"请求失败: {str(e)}")
# 由于这里并没有测试数据,但是逻辑是这样写的在这里。
def clear_button_clicked(self):
# 清空textBrowser,清空文本框,清空表格
self.ui.textBrowser.clear()
self.ui.lineEdit.clear()
self.ui.textEdit.clear()
# 清空表格
self.ui.tableWidget.clearContents()
if __name__ == '__main__':
app = QApplication(sys.argv)
mainWindow = mainWindow()
mainWindow.show()
sys.exit(app.exec_())