本表单适用于前后端分离项目,将表单信息提交到后端。
思路:
1.定义一个表单组件,为了使表单组件更加通用,这里采用通过遍历参数的方式,动态添加输入框的数量,同时,表单数据通常要提交到不同后端接口,因此构造函数中也将后端url 作为参数传进来。因此,我们的构造函数需要两个参数:parm(请求参数)和 url 请求地址。不需要请求后端可以不传。
class InputDialog(QWidget):
form_Signal = Signal(dict) #定义一个信号
inputs = [] # 用于存储QLineEdit对象的列表
def __init__(self, data, url=None):
super().__init__()
self.initUI(data)
self.url = url
2.通过遍历请求参数添加输入框,我在这里稍微加了点样式,使表单更大(年纪轻轻已经有点老花眼了。。。)
# data 是个字典,包含了请求参数, 输入框数量, 输入框的标签等信息
def initUI(self, data):
# 主布局
main_layout = QVBoxLayout()
# 表单布局
self.bigInputLayout = QFormLayout()
font = self.font()
font.setPointSize(14) # 示例:设置字体大小为14pt
# style设置标签和输入框的样式
label_style = """
QLabel {
min-width: 60px; /* 示例:设置QLabel的最小宽度 */
}
"""
line_edit_style = """
QLineEdit {
min-width: 500px; /* 示例:设置QLineEdit的最小宽度 */
min-height: 60px; /* 示例最小高度 */
}
"""
# 遍历请求参数,为每个参数创建一个标签和一个输入框
for item in data:
# 创建 QLabel 并设置样式和字体 (标签)
label = QLabel(item['title'], self)
label.setStyleSheet(label_style)
label.setFont(font) # 示例:设置字体
# 创建 QLineEdit 并设置样式、字体 (输入框)
input = QLineEdit(self)
input.setStyleSheet(line_edit_style)
input.setFont(font) # 示例:设置字体
print(f"将QLineEdit对象添加到列表中,添加项为{input}")
# 这个是设置只读参数,有些参数需要从点击的地方获取,一并传过来
if "value" in item and item and item["value"] is not None:
input.setText(item["value"])
input.setDisabled(True)
# 检查是否有占位符信息并且不为None,如果有则设置 (输入框中的提示)
if "placeholder" in item and item["placeholder"] is not None:
input.setPlaceholderText(item["placeholder"])
self.inputs.append(input) # 将QLineEdit对象添加到列表中
# 添加到布局
self.bigInputLayout.addRow(label, input)
main_layout.addLayout(self.bigInputLayout)
3.添加按钮
# 创建按钮布局
button_layout = QHBoxLayout()
#创建按钮
self.ok_button = QPushButton('确定', self) #确定按钮
self.cancel_button = QPushButton('取消', self)
#点击按钮连接到点击事件
self.ok_button.clicked.connect(lambda: self.on_ok_clicked(data))
self.cancel_button.clicked.connect(self.close)
#将按钮组件添加到按钮布局中
button_layout.addWidget(self.ok_button)
button_layout.addWidget(self.cancel_button)
#将按钮布局添加到主布局中
main_layout.addLayout(button_layout)
# 设置main_layout 为表单弹框主布局
self.setLayout(main_layout)
# 设置标题
self.setWindowTitle('输入信息')
4.实现按钮点击事件,这里需要定义四个方法:
(1)请求后端接口的方法,因为我请求的这个接口没有鉴权,不需要携带token,所以我是直接发送的请求。
def send_http_request(self, params):
try:
response = requests.post(self.url, json=params)
response.raise_for_status() # 如果响应状态不是200,将抛出HTTPError异常
return response.json() # 假设API返回JSON格式的数据
except requests.exceptions.RequestException as e:
print(f"HTTP请求发生错误: {e}")
return None
(2)设置回调的方法(有些需要将接口返回信息返回给主界面进行显示,或是进一步处理。如果这里的点击事件是长耗时事件,则不推荐使用回调的方式返回消息,而是通过发射信号到槽函数处理)这里传入的callback 是处理消息的函数
# 设置回调
def set_callback(self, callback=None):
self.callback = callback
(3)清理组件,pySide6 有组件复用机制,再次创建同一表单时,会导致信息交叉残留,因此我们在使用完就销毁这个表单,再次使用时临时创建就可以了, 当然, 表单页面右上角的关闭按钮也要重写, 调用一下这个方法
# 销毁组件, 防止组件复用导致的数据错误
def recreate_input_widgets(self):
# 清理旧部件
for input in self.inputs:
# 清空文本
input.setText("")
# 移除部件
self.bigInputLayout.removeWidget(input)
# 销毁部件
input.deleteLater()
# 清空列表
self.inputs.clear()
self.close()
(4)点击确定按钮连接到的事件
def on_ok_clicked(self, data):
# 创建一个空的字典作为请求体
param = {}
# 这里的data是创建组件时传过来的,是一个字典列表,每个item是一个字典
for item in data:
# 逐项向param中添加键值对,构建请求体
param.update({item['title']: self.inputs[j].text()})
# 调用请求方法,这里可以判断下 url 是否为空
if self.url is None:
#直接把param 发射出去
self.form_Signal.emit(param)
response_data = self.send_http_request(param)
if response_data is not None:
print("接口返回数据:", response_data)
# 如果设置了回调函数,则将返回数据传给回调函数,或者通过Singal发射出去
if self.callback is not None:
self.callback(response_data) # 调用回调函数传递数据
# 或者通过信号把请求响应发出去,推荐下边的做法,要在主函数中连接信号与槽
# self.form_Signal.emit(param)
self.close()
else:
print("请求失败或未收到数据")
QMessageBox.information(self, "请求失败", "请检查接口信息!")
#调用组件销毁方法
self.recreate_input_widgets()
5.重写页面关闭事件
# 重写页面关闭事件
def closeEvent(self, event):
self.recreate_input_widgets()
event.accept()
6.测试一下,看,参数大概就这个样子,注意这个main()方法是用来测试的,要写在类外边。测试通过后删掉就好,这个url 可以用自己实际的,
def main():
params = [
{
"title": "id"
},
{
"title": "io1",
"placeholder": "请输入继电器io1, 例如: 1或0"
},
{
"title": "io2",
"placeholder": "请输入io2"
},
{
"title": "io3",
"placeholder": "请输入io3"
},
{
"title": "io4",
"placeholder": "请输入io4"
},
{
"title": "io5",
"placeholder": "请输入io5"
}
]
app = QApplication([])
url = "http://localhost:8080" + "/setIo" # 填写自己实际的url
dialog = InputDialogForList(params,url)
dialog.show()
app.exec()
if __name__ == "__main__":
main()
7.运行结果
8.导入的依赖:
from PySide6.QtWidgets import QApplication, QWidget, QVBoxLayout, QHBoxLayout, QLineEdit, QPushButton, QDialog, QLabel, \
QMessageBox, QFormLayout
import requests