PySide2下如何动态添加和移除widgets和layouts

前言

在软件开发的过程中,需要在对话框中动态添加和移除控件对象,并且对话框需要根据窗口内容的变化自适应调整自身大小(目前只能自适应变大,不能自适应变小,后续有机会再修改)。
下面是代码运行效果截图:

  1. 代码启动页面
    PySide2下如何动态添加和移除widgets和layouts_第1张图片
  2. 动态增加窗口内容
    PySide2下如何动态添加和移除widgets和layouts_第2张图片
  3. 动态移除窗口内容
    PySide2下如何动态添加和移除widgets和layouts_第3张图片

代码

开发环境:Python3.7 + PySide2
PyQt5实现方式基本相同。

import sys
import numpy as np
from PySide2.QtWidgets import QDialog, QWidget, QGridLayout, QVBoxLayout, QHBoxLayout, QLabel, QPushButton, \
    QLineEdit, QMessageBox, QApplication


class SetTimeStepDlg(QDialog):
    def __init__(self):
        super(SetTimeStepDlg, self).__init__()
        self.setWindowTitle('设置模型步长参数')
        self.value_widets_list = []
        self.row_lot_list = []
        self.initUI()

    def initUI(self):
        main_lot = QVBoxLayout()  # 垂直布局,主布局
        self.rows_widets_lot = QVBoxLayout()  # 垂直布局,存储行标签和值控件的布局
        for i in range(4):
            self.generate_row_widget()
        self.add_row_btn = QPushButton('增加一行')
        self.del_row_btn = QPushButton('删除一行')
        ok_btn = QPushButton("确定")
        cancel_btn = QPushButton("取消")
        self.add_row_btn.clicked.connect(self.add_row_widget)
        self.del_row_btn.clicked.connect(self.del_row_widget)
        ok_btn.clicked.connect(self.accept)
        cancel_btn.clicked.connect(self.reject)
        hlayout = QHBoxLayout()  # 水平布局,存储按钮控件
        hlayout.addWidget(self.add_row_btn)
        hlayout.addWidget(self.del_row_btn)
        hlayout.addWidget(ok_btn)
        hlayout.addWidget(cancel_btn)
        main_lot.addLayout(self.rows_widets_lot)
        main_lot.addLayout(hlayout)
        self.setLayout(main_lot)  # 将主布局设置为对话框的布局
        self.show()  # 显示对话框

    def add_row_widget(self):
        self.generate_row_widget()
        if not self.del_row_btn.isEnabled():
            self.del_row_btn.setEnabled(True)

    def del_row_widget(self):
        # 动态删除行布局(即存储行标签和值控件的布局)
        if self.rows_widets_lot.count() > 0:
            while self.row_lot_list[-1].count():
                item = self.row_lot_list[-1].takeAt(0)
                widget = item.widget()
                if widget is not None:
                    widget.deleteLater()
            del self.row_lot_list[-1]
            del self.value_widets_list[-1]
        if len(self.row_lot_list) < 1:
            self.del_row_btn.setEnabled(False)
            return

    def generate_row_widget(self):
        """生成一行标签和值控件"""
        start_lbl = QLabel('开始时间')
        start_le = QLineEdit('0')
        end_lbl = QLabel('结束时间')
        end_le = QLineEdit('100')
        step_lbl = QLabel('步长')
        step_le = QLineEdit('1')
        unit_lbl = QLabel('年')

        lot = QHBoxLayout()
        lot.addWidget(start_lbl)
        lot.addWidget(start_le)
        lot.addWidget(end_lbl)
        lot.addWidget(end_le)
        lot.addWidget(step_lbl)
        lot.addWidget(step_le)
        lot.addWidget(unit_lbl)
        self.row_lot_list.append(lot)
        self.rows_widets_lot.addLayout(lot)
        self.value_widets_list.append([start_le, end_le, step_le])

    def accept(self):
        values = []
        for i in range(len(self.value_widets_list)):
            row = self.value_widets_list[i]
            start = int(row[0].text())
            end = int(row[1].text())
            step = int(row[2].text())
            if step > end - start or (end - start) % step != 0:
                return
            values.append([start, end, step])
        QDialog.accept(self)


if __name__ == '__main__':
    app = QApplication(sys.argv)
    dlg = SetTimeStepDlg()
    sys.exit(app.exec_())

参考资料

[1] How to dynamically add and remove widgets and layouts in PyQt5


以上,欢迎评论交流~

你可能感兴趣的:(PySide2,软件开发,qt,PySide2,PyQt5,Python,layout)