前言
在软件开发的过程中,需要在对话框中动态添加和移除控件对象,并且对话框需要根据窗口内容的变化自适应调整自身大小(目前只能自适应变大,不能自适应变小,后续有机会再修改)。
下面是代码运行效果截图:
- 代码启动页面
- 动态增加窗口内容
- 动态移除窗口内容
代码
开发环境: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
以上,欢迎评论交流~