pySide6通用表单组件

本表单适用于前后端分离项目,将表单信息提交到后端。

思路:

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

  • 8
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值