数据处理是一件麻烦且费时的事情,不知道大家有没有感受,测试可能就1分钟,但数据处理却可能要2小时。工作中通常需要对CAE、测试数据进行后处理,比如对CAE瞬态位移曲线、振动数据等进行FFT、收敛时间分析、积分等。
MATLAB或Python程序来进行数据处理是我们最常用的方法,但是不够灵活,流程也不固化。作为一个驰骋CAE领域多年的老司机该是展现实力的时候了,仿真社将推出系列文章借助AI模型协助开发基于PyQt5的GUI界面软件,将常用的数据处理功能进行软件封装。下次出差,别人是抱着笨重的电脑,那你,只需带着exe文件就行。
Hyperview是公认的最优秀的CAE后处理软件,我需要借鉴和参考它的一些功能以及界面风格。
数据处理大多数时候都需要多窗口显示数据状态,类似Hyperview,可以有2窗口,4窗口,8窗口等。这个功能在PyQt5里就是QMdiArea控件。

hyperview多窗口界面
本文将实现多窗口QMdiArea的功能,默认1个窗口,可选择2窗口水平排列,2窗口垂直排列,4窗口排列,类似上图Hyperview中多窗口。
我的设计将会涉及到两部分,界面设计部分将在QtDesigner软件实现,分窗功能将借助AI模型(通义千问)来实现。
1
1.打开Qt软件,使用MainWindow主窗口
2.分窗功能放在菜单栏显示下方,如下图所示

3.将需要用到的图标提前保存路径中
4.资源管理器的方法将图片加载到相应位置

5.将图标通过icon赋给相应的功能菜单

6.添加工具栏

7.将图标拖拽到工具栏,如图所示

8.将保存的界面文件用UIC转换为ui_dataSoftware.py文件
2
代码如下:
import sysfrom PyQt5.QtWidgets import (QApplication, QMainWindow, QMdiArea,QMdiSubWindow,QWidget,QVBoxLayout, QLabel, QDesktopWidget,QMenu,QAction)from PyQt5.QtCore import Qtfrom PyQt5.QtGui import QColor, QPaletteclass ContentWidget(QWidget):"""子窗口内容区域"""def __init__(self,window_id):super().__init__()layout = QVBoxLayout()layout.setContentsMargins(20, 20,20, 20)label = QLabel(f"窗口 {window_id}")label.setStyleSheet("font-size:24px; color: #333; background-color: #f0f0f0; padding: 20px;")label.setAlignment(Qt.AlignCenter)layout.addWidget(label)self.setLayout(layout)class MainWindow(QMainWindow):def __init__(self):super().__init__()self.setWindowTitle("QMdiArea多窗口布局示例")self.setGeometry(100, 100, 1000, 700)# 创建QMdiAreaself.mdi_area = QMdiArea()self.setCentralWidget(self.mdi_area)# 设置QMdiArea选项self.mdi_area.setOption(QMdiArea.DontMaximizeSubWindowOnActivation,True)# 创建菜单栏self.create_menu()# 创建默认的单个子窗口self.create_default_window()# 确保窗口显示后自动填满self.showMaximized()self.show_single_window()def create_menu(self):"""创建菜单栏"""menu_bar= self.menuBar()# 窗口布局菜单layout_menu = menu_bar.addMenu("窗口布局")# 添加布局选项action_single = QAction("单窗口", self)action_single.triggered.connect(self.show_single_window)layout_menu.addAction(action_single)action_horizontal = QAction("水平平铺", self)action_horizontal.triggered.connect(self.show_horizontal_windows)layout_menu.addAction(action_horizontal)action_vertical = QAction("垂直平铺", self)action_vertical.triggered.connect(self.show_vertical_windows)layout_menu.addAction(action_vertical)action_four = QAction("四窗口平铺", self)action_four.triggered.connect(self.show_four_windows)layout_menu.addAction(action_four)# 添加退出选项exit_action = QAction("退出", self)exit_action.triggered.connect(self.close)menu_bar.addAction(exit_action)def create_default_window(self):"""创建默认的单个子窗口"""self.create_sub_window("默认窗口", 1)def create_sub_window(self, title,window_id):"""创建子窗口"""sub_window= QMdiSubWindow()sub_window.setWindowTitle(f"{title}- {window_id}")sub_window.setWidget(ContentWidget(window_id))sub_window.setWindowFlags(Qt.Window)self.mdi_area.addSubWindow(sub_window)return sub_windowdef show_single_window(self):"""显示单个窗口(自动填满QMdiArea)"""sub_windows= self.mdi_area.subWindowList()if not sub_windows:return# 显示第一个窗口,隐藏其他for i, sub_window in enumerate(sub_windows):if i == 0:sub_window.show()else:sub_window.hide()# 确保QMdiArea的大小已经确定self.mdi_area.setActiveSubWindow(sub_windows[0])# 手动设置窗口大小为QMdiArea的大小mdi_rect = self.mdi_area.rect()sub_windows[0].setGeometry(0, 0,mdi_rect.width(), mdi_rect.height())def show_horizontal_windows(self):"""水平显示两个窗口"""sub_windows= self.mdi_area.subWindowList()if len(sub_windows) < 2:# 如果窗口不足,创建两个self.create_sub_window("窗口1", 1)self.create_sub_window("窗口2", 2)sub_windows = self.mdi_area.subWindowList()# 确保只显示前两个窗口for i, sub_window in enumerate(sub_windows):if i < 2:sub_window.show()else:sub_window.hide()# 获取屏幕尺寸screen_geometry =QDesktopWidget().screenGeometry()width = screen_geometry.width()// 2height = screen_geometry.height()# 设置两个窗口的大小和位置self.mdi_area.setActiveSubWindow(sub_windows[0])sub_windows[0].setGeometry(0, 0,width, height)self.mdi_area.setActiveSubWindow(sub_windows[1])sub_windows[1].setGeometry(width,0, width, height)def show_vertical_windows(self):"""垂直显示两个窗口"""sub_windows= self.mdi_area.subWindowList()if len(sub_windows) < 2:# 如果窗口不足,创建两个self.create_sub_window("窗口1", 1)self.create_sub_window("窗口2", 2)sub_windows = self.mdi_area.subWindowList()# 确保只显示前两个窗口for i, sub_window in enumerate(sub_windows):if i < 2:sub_window.show()else:sub_window.hide()# 获取屏幕尺寸screen_geometry =QDesktopWidget().screenGeometry()width = screen_geometry.width()height = screen_geometry.height()// 2# 设置两个窗口的大小和位置self.mdi_area.setActiveSubWindow(sub_windows[0])sub_windows[0].setGeometry(0, 0,width, height)self.mdi_area.setActiveSubWindow(sub_windows[1])sub_windows[1].setGeometry(0,height, width, height)def show_four_windows(self):"""四窗口平铺(填满屏幕)"""sub_windows= self.mdi_area.subWindowList()if len(sub_windows) < 4:# 如果窗口不足,创建四个for i in range(4 - len(sub_windows)):self.create_sub_window(f"窗口{len(sub_windows) + i + 1}", len(sub_windows) + i + 1)sub_windows = self.mdi_area.subWindowList()# 确保只显示前四个窗口for i, sub_window in enumerate(sub_windows):if i < 4:sub_window.show()else:sub_window.hide()# 获取屏幕尺寸screen_geometry =QDesktopWidget().screenGeometry()width = screen_geometry.width()// 2height = screen_geometry.height()// 2# 设置四个窗口的大小和位置self.mdi_area.setActiveSubWindow(sub_windows[0])sub_windows[0].setGeometry(0, 0,width, height)self.mdi_area.setActiveSubWindow(sub_windows[1])sub_windows[1].setGeometry(width,0, width, height)self.mdi_area.setActiveSubWindow(sub_windows[2])sub_windows[2].setGeometry(0,height, width, height)self.mdi_area.setActiveSubWindow(sub_windows[3])sub_windows[3].setGeometry(width,height, width, height)if __name__ == "__main__":app = QApplication(sys.argv)window = MainWindow()window.show()sys.exit(app.exec_())
3
将上述功能核心代码复 制到ui_dataSoftware.py文件下的函数Ui_MainWindow下,对比Mdi_test.py文件的核心逻辑,有几处需要更改,主要原因是ui文件转换py后函数父对象是MainWindow但是函数AI产生的代码父对象是QMainWidow。


