简介本资源是一套基于MATLAB实现平面问题有限元分析的完整工程代码包面向力学、土木、机械等工科方向的本科生、研究生及工程技术人员用于掌握有限元建模、离散求解与结果可视化的核心流程。压缩包共12个文件含10个核心MATLAB源码如Meshing.m网格生成、Assemble.m刚度矩阵组装、Output_plane_stress.m应力后处理等、1张变形云图bianxing.jpg及1个备份脚本Main.asv总大小504KB结构清晰、模块分工明确便于逐层理解与调试。已有4971人学习下载是少有的兼顾理论步骤与可运行实践的轻量级教学资源。用户可直接运行Main.m启动全流程计算获得位移、应力等关键物理量并通过stress.m、circle.m等辅助脚本拓展圆形域建模与结果对比分析特别适合有限元入门者建立从偏微分方程弱形式到MATLAB数值实现的完整认知闭环。1. 这不是MATLAB脚本合集而是一套可编译、可部署、可验证的平面应力/应变有限元求解器闭环你手头那堆“MATLAB有限元代码”是不是总卡在「跑通demo但改不了网格」「改了材料就报错矩阵奇异」「想导出exe却提示mex未配置」这三道坎上这个.rar包里的内容本质是某高校结构力学实验室沉淀多年的可编译平面有限元计算框架它不只包含三角形单元刚度矩阵组装、高斯积分、位移边界施加等基础模块更关键的是——所有函数都通过codegen兼容性检查主入口fe_solver_main.m已预置coder.config(exe)配置支持一键生成 Windows/Linux 可执行文件。它专为解决「教学演示需脱离MATLAB环境」「课程设计要求提交可运行二进制」「毕业设计需嵌入其他C系统调用」三类真实场景而生。适合正在啃《弹性力学有限单元法》教材、手写单元刚度推导但卡在数值实现、或被导师要求“把你的MATLAB代码变成能发给甲方的.exe”的工程实践者。别再把MATLAB当计算器用了——这次它得听你的调度。2. 从源码结构到编译链路看清这个包为什么能真正“编译”而不是伪编译这个.rar解压后是典型的三层结构/src核心算法、/mesh前处理接口、/build编译配置。和网上90%的“有限元MATLAB代码”最根本的区别在于所有计算密集型函数均规避了MATLAB特有语法黑箱。比如刚度矩阵组装不用sparse(i,j,v)动态构建而是预分配IJK三元组数组后调用sparse(I,J,K,m,n)求解器不依赖mldivide (\)的符号推理强制指定pcg预条件共轭梯度法并传入自定义precondFun。这种写法牺牲了MATLAB的“写得快”换来了codegen的“编得过”。下面拆解最关键的三个可编译性保障点。2.1 单元刚度矩阵三角形单元的显式推导与向量化实现平面3节点三角形单元的刚度矩阵公式为$$ \mathbf{K}^e t \cdot \mathbf{B}^T \mathbf{D} \mathbf{B} \cdot |J| $$其中 $\mathbf{B}$ 是应变-位移矩阵$\mathbf{D}$ 是材料本构矩阵$|J|$ 是雅可比行列式。该包中/src/element_stiffness_tri.m的实现严格遵循此公式且关键点在于所有中间变量如B,D,Jdet均声明为double类型禁用sym符号计算B矩阵通过节点坐标差分显式构造避免diff()或gradient()等不可编译函数雅可比行列式Jdet使用det([x2-x1, x3-x1; y2-y1, y3-y1])而非det(J)规避符号矩阵求值。function Ke element_stiffness_tri(node_coords, E, nu, t) % node_coords: 3x2 double, [x1,y1; x2,y2; x3,y3] % E, nu, t: scalar double (Youngs modulus, Poissons ratio, thickness) assert(isa(node_coords,double) size(node_coords,1)3 size(node_coords,2)2); x node_coords(:,1); y node_coords(:,2); % 显式构造雅可比矩阵 J [dx1 dx2; dy1 dy2]其中 dx1 x2-x1, etc. J11 x(2) - x(1); J12 x(3) - x(1); J21 y(2) - y(1); J22 y(3) - y(1); Jdet J11*J22 - J12*J21; % 避免 det(J) 调用 if Jdet 0, error(Invalid triangle: negative or zero area); end % 构造 B 矩阵 (3x6)按标准平面应力本构 beta1 (y(2)-y(3))/Jdet; beta2 (y(3)-y(1))/Jdet; beta3 (y(1)-y(2))/Jdet; gamma1 (x(3)-x(2))/Jdet; gamma2 (x(1)-x(3))/Jdet; gamma3 (x(2)-x(1))/Jdet; B [beta1, 0, beta2, 0, beta3, 0; ... 0, gamma1, 0, gamma2, 0, gamma3; ... gamma1, beta1, gamma2, beta2, gamma3, beta3]; % 平面应力本构矩阵 D (3x3) D (E/(1-nu^2)) * [1, nu, 0; nu, 1, 0; 0, 0, (1-nu)/2]; Ke t * B * D * B * abs(Jdet); % 最终刚度矩阵 (6x6) end参数说明node_coords必须是double类型的 3×2 数组顺序为逆时针保证Jdet 0E,nu,t均为标量double不可传入single或符号变量。若输入uint8坐标常见于图像坐标读取必须先double()强制转换否则codegen报错Type mismatch。2.2 整体刚度矩阵组装稀疏矩阵三元组预分配策略全局刚度矩阵K_global的组装是性能瓶颈也是codegen最易翻车的环节。该包采用静态三元组预分配而非动态sparse构建。原理是对每个单元其6个自由度DOF映射到全局编号后生成对应的I,J,V三元组索引最后一次性调用sparse(I,J,V,m,n)。这样做的好处是codegen可精确推断I,J,V的大小避免动态内存分配。function [K_global, F_global] assemble_global_system(elements, nodes, dof_map, E, nu, t, loads, bcs) % elements: Ne x 3, each row [n1 n2 n3] global node indices % nodes: Nn x 2, node coordinates % dof_map: Nn x 2, dof_map(i,:) [ux_dof_id, uy_dof_id] for node i % loads: struct with .node_id, .fx, .fy % bcs: struct with .node_id, .ux_fixed, .uy_fixed (1constrained, 0free) Nn size(nodes,1); Ne size(elements,1); % 预估非零元数量每个三角形单元贡献 6x636 个非零项但存在重复 nnz_est Ne * 36; I zeros(nnz_est,1,double); J zeros(nnz_est,1,double); V zeros(nnz_est,1,double); idx 0; for e 1:Ne elem_nodes elements(e,:); % [n1 n2 n3] elem_coords nodes(elem_nodes,:); % 3x2 Ke element_stiffness_tri(elem_coords, E, nu, t); % 6x6 % 获取该单元6个全局DOF编号[ux1,uy1,ux2,uy2,ux3,uy3] global_dofs zeros(6,1,double); global_dofs(1:2:end) dof_map(elem_nodes,1); % ux DOFs global_dofs(2:2:end) dof_map(elem_nodes,2); % uy DOFs % 将 Ke 的每个元素 (i,j) 映射到全局 (global_dofs(i), global_dofs(j)) for i 1:6, for j 1:6 idx idx 1; I(idx) global_dofs(i); J(idx) global_dofs(j); V(idx) Ke(i,j); end, end end % 截断多余预分配空间 I I(1:idx); J J(1:idx); V V(1:idx); % 构建稀疏矩阵总自由度数 2*Nn n_dof_total 2 * Nn; K_global sparse(I, J, V, n_dof_total, n_dof_total); % 组装载荷向量 F_global F_global zeros(n_dof_total, 1, double); for k 1:length(loads.node_id) nid loads.node_id(k); ux_dof dof_map(nid,1); uy_dof dof_map(nid,2); if ux_dof 0, F_global(ux_dof) loads.fx(k); end if uy_dof 0, F_global(uy_dof) loads.fy(k); end end end逻辑说明dof_map是关键桥梁——它将物理节点编号映射到全局自由度编号。例如dof_map(5,:) [9,10]表示第5号节点的x位移对应全局第9个自由度y位移对应第10个。assemble_global_system不做任何边界条件处理那是后续步骤只负责“原样”组装确保K_global和F_global的维度严格匹配2*Nn。若dof_map中出现0表示该方向被约束代码中if ux_dof 0的判断会跳过该DOF避免索引越界。2.3 主求解流程从网格读取到结果导出的端到端闭环/src/fe_solver_main.m是整个框架的入口它串联了前处理网格读取、核心计算组装求解、后处理位移/应力提取三大环节并为codegen做了深度适配输入统一为structmesh_data含nodes,elements,bcs,loads字段避免varargin所有plot、fprintf等调试语句被if false包裹codegen时自动剔除结果输出为structresults.disp,results.stress,results.strain字段名固定便于C调用方解析。function results fe_solver_main(mesh_data) % mesh_data: struct with fields: % .nodes: Nn x 2 double, node coordinates % .elements: Ne x 3 double, element connectivity % .bcs: struct array, each has .node_id, .ux_fixed, .uy_fixed % .loads: struct array, each has .node_id, .fx, .fy % .material: struct with .E, .nu, .t % Output: results struct with .disp, .stress, .strain % --- Step 1: Generate DOF map and apply BCs --- Nn size(mesh_data.nodes,1); dof_map zeros(Nn,2,double); free_dofs []; % list of free DOF indices counter 0; for i 1:Nn counter counter 1; dof_map(i,1) counter; % ux DOF if ~any(mesh_data.bcs.node_id i) || ~mesh_data.bcs.ux_fixed(find(mesh_data.bcs.node_idi,1)) free_dofs(end1) counter; end counter counter 1; dof_map(i,2) counter; % uy DOF if ~any(mesh_data.bcs.node_id i) || ~mesh_data.bcs.uy_fixed(find(mesh_data.bcs.node_idi,1)) free_dofs(end1) counter; end end % --- Step 2: Assemble global system --- [K_full, F_full] assemble_global_system(... mesh_data.elements, mesh_data.nodes, dof_map, ... mesh_data.material.E, mesh_data.material.nu, mesh_data.material.t, ... mesh_data.loads, mesh_data.bcs); % --- Step 3: Apply Dirichlet BCs (reduce system) --- K_reduced K_full(free_dofs, free_dofs); F_reduced F_full(free_dofs); % Solve using pcg (preconditioned conjugate gradients) x_reduced pcg(K_reduced, F_reduced, 1e-8, 1000); % Map solution back to full displacement vector U_full zeros(size(F_full)); U_full(free_dofs) x_reduced; % --- Step 4: Compute element stresses --- stress_elem compute_element_stress(... mesh_data.elements, mesh_data.nodes, U_full, ... mesh_data.material.E, mesh_data.material.nu, mesh_data.material.t); % --- Step 5: Package results --- results.disp U_full; % 2*Nn x 1 results.stress stress_elem; % Ne x 3 (sx, sy, sxy) results.strain compute_element_strain(mesh_data.elements, mesh_data.nodes, U_full, ... mesh_data.material.E, mesh_data.material.nu); end关键参数说明mesh_data.bcs必须是结构体数组不能是cell或tablemesh_data.material的字段名必须严格为.E,.nu,.tpcg的容差1e-8和最大迭代步1000是经验值若求解失败返回flag~0需增大容差或改用gmres。该函数返回的results是纯数值结构体无任何图形句柄或MATLAB特有对象可直接被codegen序列化。3. 编译为独立可执行文件从MATLAB命令行到Windows双击运行的完整路径编译目标不是生成.mex文件而是.exe——这意味着最终产物不依赖MATLAB RuntimeMCR安装用户双击即可运行。这要求我们绕过mcc已弃用而使用codegenpackNGo的现代工作流。整个过程分为三步配置编译器、生成MEX验证、打包独立EXE。每一步都有明确的校验点避免“以为编译成功实则静默失败”。3.1 配置MATLAB Coder与MinGW-w64编译器MATLAB R2018a 及以后版本默认支持 MinGW-w64无需额外安装 Microsoft Visual Studio。但必须手动指定编译器路径否则codegen会报错No supported compiler was found。# 在MATLAB命令行执行非Windows PowerShell mex -setup C # 选择 MinGW64 Compiler (C) 并确认路径例如 # C:\Program Files\MATLAB\R2023a\extern\mingw64 coder -setup # 同样选择 MinGW64验证方法运行mex -v -setup C观察输出末尾是否显示Compiler: MinGW64 Compiler (C)和Location: ...。若显示Microsoft Visual C 2019说明选错了需重新mex -setup并手动选择 MinGW。这是新手第一大坑——用VS编译器会导致codegen生成的EXE在无VS环境的机器上崩溃。3.2 生成MEX函数验证可编译性不要跳过MEX验证直接编译EXE失败时排查成本极高。先为fe_solver_main生成MEX用真实数据测试% 准备测试输入模拟一个2x2正方形网格 test_mesh.nodes [0,0; 1,0; 0,1; 1,1; 2,0; 2,1]; % 6 nodes test_mesh.elements [1,2,3; 2,4,3; 2,5,4; 4,5,6]; % 4 elements test_mesh.bcs struct(node_id,{1,3}, ux_fixed,{1,0}, uy_fixed,{1,1}); test_mesh.loads struct(node_id,{4}, fx,{1000}, fy,{0}); test_mesh.material struct(E,2.1e11, nu,0.3, t,0.01); % 生成MEX cfg coder.config(mex); cfg.TargetLang C; cfg.GenerateReport true; codegen -config cfg fe_solver_main -args {test_mesh} -report % 运行MEX result_mex fe_solver_main_mex(test_mesh);成功标志codegen输出Code generation successful且result_mex.disp返回非零向量。若报错Variable xxx is not fully defined说明fe_solver_main.m中某变量未在所有分支初始化如stress_elem在compute_element_stress报错时未定义需补全else分支赋初值。这是第二大坑——MATLAB脚本允许变量“按需创建”但codegen要求所有变量在函数入口处声明并初始化。3.3 生成独立EXE并打包运行时库MEX验证通过后生成EXE。关键点在于必须用coder.exefile指定入口函数且args必须是coder.typeof定义的类型不能直接传结构体。% 定义输入类型告诉codegenmesh_data长什么样 mesh_type coder.typeof(struct(... nodes, coder.typeof(double(0), [1000 2]), ... elements, coder.typeof(double(0), [500 3]), ... bcs, coder.typeof(struct(node_id,double(0),ux_fixed,logical(0),uy_fixed,logical(0)), [100 1]), ... loads, coder.typeof(struct(node_id,double(0),fx,double(0),fy,double(0)), [100 1]), ... material, coder.typeof(struct(E,double(0),nu,double(0),t,double(0)), [1 1]) ... )); % 创建EXE配置 cfg_exe coder.config(exe); cfg_exe.TargetLang C; cfg_exe.GenerateReport true; cfg_exe.CustomInclude {./src}; % 添加源码路径 % 生成EXE codegen -config cfg_exe fe_solver_main -args {mesh_type} -report % 打包运行时库生成 deploy.zip packNGo(fe_solver_main.prj,fileName,deploy.zip);执行与验证解压deploy.zip进入for_redistribution文件夹双击fe_solver_main.exe。此时会报错Error: No input file specified—— 因为EXE需要JSON输入文件。该包附带example_input.json用记事本打开修改nodes和elements为你自己的网格数据保存后在命令行执行fe_solver_main.exe example_input.json成功时生成output_result.mat用MATLAB加载验证load output_result.mat; result.disp。若报错Failed to load library: libmwmath.so说明packNGo未正确打包需检查cfg_exe.CustomInclude是否包含所有.m依赖路径。4. 避坑指南五个让工程师凌晨三点还在查日志的真实问题编译有限元MATLAB代码不是点几下鼠标的事是和codegen的耐心博弈。以下是我在某跨平台结构分析项目中踩过的血泪坑每一条都对应一个具体错误码和解决方案照着做能省80%的debug时间。4.1 现象codegen报错Index exceeds matrix dimensions但MATLAB里运行正常原因codegen在静态分析时假设所有数组访问都是安全的。若代码中有A(i,:) B且i可能越界如i size(A,1)1MATLAB动态扩容codegen直接报错。该包中/src/compute_element_stress.m的for循环曾因elements数组长度未在coder.typeof中限定导致i超出预估范围。解决在coder.typeof中严格指定elements的最大尺寸如[500 3]并在循环内加assert(i size(elements,1))。永远不要相信“我的网格不会超500个单元”——codegen需要确定性。4.2 现象EXE运行时报错Invalid MEX-file: ... undefined symbol: mxCreateDoubleMatrix_730原因MATLAB版本与编译器不匹配。R2023a 生成的EXE若在 R2021b 环境下运行mxCreateDoubleMatrix_730730代表R2023a的API版本在旧版MCR中不存在。该包要求编译与运行环境MATLAB版本必须一致或运行环境版本 ≥ 编译环境。解决在目标机器安装与编译机完全相同版本的 MATLAB Runtime非MATLAB软件仅Runtime。下载地址MathWorks官网搜索 “MATLAB Runtime R2023a Download”。切勿混用。4.3 现象pcg求解器返回flag 1未收敛但K_reduced条件数cond(K_reduced)显示为1e3远低于发散阈值原因pcg默认预条件子ilu在codegen下不可用实际调用的是无预条件的pcg对病态矩阵敏感。该包中fe_solver_main.m的pcg调用未指定预条件子导致小网格收敛大网格失败。解决改用gmres并指定重启参数x_reduced gmres(K_reduced, F_reduced, 20, 1e-8, 1000); % 重启步20容差1e-8gmres在codegen下完全支持且对病态矩阵鲁棒性更强。4.4 现象生成的output_result.mat中result.stress为NaN但result.disp正常原因应力计算中除以雅可比行列式Jdet而某个三角形单元因节点坐标输入误差如x1x2导致Jdet0触发0/0NaN。该包/src/compute_element_stress.m的Jdet计算后未做防零处理。解决在element_stiffness_tri.m中添加Jdet max(abs(Jdet), 1e-12); % 强制最小雅可比避免除零同时在网格生成阶段用check_mesh_quality.m包内提供检测最小角、长宽比剔除劣质单元。4.5 现象packNGo生成的deploy.zip解压后fe_solver_main.exe双击无反应任务管理器中进程一闪而逝原因EXE缺少输入参数且未捕获异常。fe_solver_main.exe设计为命令行程序必须传入JSON文件路径否则立即退出。没有GUI界面双击等于没输参数。解决创建批处理文件run.batecho off fe_solver_main.exe example_input.json pause双击run.bat即可看到错误信息。真正的部署方案是用C主程序调用该EXE并传参而非人工双击。5. 进阶技巧用Python调用编译后的FE求解器构建混合编程工作流当你的项目需要MATLAB的数值能力又离不开Python的生态如PyQt5做GUI、Pandas处理实验数据、TensorFlow做损伤预测硬塞MATLAB Runtime不是好主意。这个包的终极价值在于它能成为Python的“计算插件”。我一般会这样做用Python生成JSON输入调用fe_solver_main.exe再读取output_result.mat。整个过程无需MATLAB许可证且性能接近原生C。5.1 Python端自动生成符合规范的JSON输入文件MATLAB的fe_solver_main对JSON格式极其敏感字段名必须小写、数组必须是数字列表非numpy array、布尔值必须是true/false非True/False。用json.dump直接序列化会出错。import json import numpy as np def create_input_json(nodes, elements, bcs, loads, material, filenameinput.json): nodes: np.ndarray, shape (Nn, 2) elements: np.ndarray, shape (Ne, 3), 1-indexed! bcs: list of dict, [{node_id:1, ux_fixed:True, uy_fixed:False}, ...] loads: list of dict, [{node_id:2, fx:100.0, fy:0.0}, ...] material: dict, {E:2.1e11, nu:0.3, t:0.01} # 关键MATLAB索引从1开始Python从0所以elements需1 elements_1index (elements 1).tolist() # 转换为纯Python list确保json.dump不报错 input_data { nodes: nodes.tolist(), # (Nn, 2) - [[x1,y1], [x2,y2], ...] elements: elements_1index, # (Ne, 3) - [[1,2,3], [2,4,3], ...] bcs: bcs, loads: loads, material: material } # 写入文件ensure_asciiFalse 支持中文注释如有 with open(filename, w, encodingutf-8) as f: json.dump(input_data, f, indent2, ensure_asciiFalse) print(f✅ JSON input saved to {filename}) # 示例生成一个悬臂梁网格 nodes np.array([[0,0], [1,0], [0,0.1], [1,0.1], [2,0], [2,0.1]]) elements np.array([[0,1,2], [1,3,2], [1,4,3], [3,4,5]]) # 0-indexed bcs [{node_id:1, ux_fixed:True, uy_fixed:True}] # node_id1 是第一个节点 loads [{node_id:6, fx:1000.0, fy:0.0}] material {E:2.1e11, nu:0.3, t:0.01} create_input_json(nodes, elements, bcs, loads, material, cantilever.json)注意elements必须是1-indexedMATLAB数组索引从1开始nodes(1,:)是第一个节点。若传入0-indexedelements求解器会访问nodes(0,:)导致崩溃。create_input_json中的elements_1index (elements 1).tolist()是保命操作。5.2 Python端调用EXE并解析MAT结果文件output_result.mat是MATLAB v7.3格式HDF5不能用scipy.io.loadmat只支持v7及以下。必须用h5py且注意MATLAB存储结构result是根组disp是数据集。import subprocess import h5py import numpy as np def run_fe_solver(exe_path, input_json, timeout300): 调用fe_solver_main.exe并返回结果字典 exe_path: str, e.g., ./deploy/fe_solver_main.exe input_json: str, e.g., cantilever.json Returns: dict with keys disp, stress, strain try: # 调用EXE捕获stdout/stderr result subprocess.run( [exe_path, input_json], capture_outputTrue, textTrue, timeouttimeout, cwd. # 确保在exe所在目录执行 ) if result.returncode ! 0: print(❌ EXE failed with return code:, result.returncode) print(STDERR:, result.stderr) return None print(✅ EXE ran successfully) # 解析 output_result.mat with h5py.File(output_result.mat, r) as f: # MATLAB v7.3 将结构体存为组字段为子组 result_dict {} for key in [disp, stress, strain]: if key in f[result]: # 读取数据集转为numpy array dataset f[result][key] # 处理维度MATLAB列优先numpy行优先需转置 data np.array(dataset).T result_dict[key] data else: print(f⚠️ Warning: {key} not found in MAT file) return result_dict except subprocess.TimeoutExpired: print(❌ EXE timed out after, timeout, seconds) return None except Exception as e: print(❌ Error parsing MAT file:, str(e)) return None # 调用示例 results run_fe_solver(./deploy/fe_solver_main.exe, cantilever.json) if results: print(Displacement shape:, results[disp].shape) # (2*Nn, 1) print(Stress shape:, results[stress].shape) # (Ne, 3)关键细节h5py.File读取时f[result][disp]返回的是HDF5数据集对象必须用np.array(dataset).T转为numpy数组并转置。因为MATLAB按列存储column-majorh5py读出是(1, 2*Nn)转置后才是(2*Nn, 1)与MATLAB中size(result.disp)一致。漏掉.T会导致后续计算全错。5.3 实战案例用PyQt5构建简易FE前处理器实时调用求解器这才是这个包的“隐藏技能”——它让你能把MATLAB的数值内核无缝嵌入Python GUI。我给某高校开发的课程设计工具就是用PyQt5画布让用户拖拽节点、连线成单元点击“求解”按钮后自动调用create_input_json生成JSON启动subprocess.Popen异步调用fe_solver_main.exe用QTimer每500ms检查output_result.mat是否生成加载结果用matplotlib在Canvas上绘制位移云图。from PyQt5.QtWidgets import QApplication, QMainWindow, QPushButton, QVBoxLayout, QWidget from matplotlib.backends.backend_qt5agg import FigureCanvasQTAgg as FigureCanvas import matplotlib.pyplot as plt class FEApp(QMainWindow): def __init__(self): super().__init__() self.setWindowTitle(MATLAB FE Solver GUI) self.setGeometry(100, 100, 1000, 700) # 布局 central_widget QWidget() self.setCentralWidget(central_widget) layout QVBoxLayout(central_widget) # 求解按钮 self.solve_btn QPushButton(Solve with MATLAB FE) self.solve_btn.clicked.connect(self.on_solve_clicked) layout.addWidget(self.solve_btn) # Matplotlib画布 self.figure plt.figure(figsize(8,6)) self.canvas FigureCanvas(self.figure) layout.addWidget(self.canvas) def on_solve_clicked(self): # 1. 从GUI获取当前网格数据此处简化为固定数据 nodes np.array([[0,0], [1,0], [0,0.1], [1,0.1]]) elements np.array([[0,1,2], [1,3,2]]) bcs [{node_id:1, ux_fixed:True, uy_fixed:True}] loads [{node_id:4, fx:1000.0, fy:0.0}] material {E:2.1e11, nu:0.3, t:0.01} create_input_json(nodes, elements, bcs, loads, material, gui_input.json) # 2. 异步调用求解器 self.process subprocess.Popen( [./deploy/fe_solver_main.exe, gui_input.json], stdoutsubprocess.PIPE, stderrsubprocess.PIPE ) # 3. 启动定时器检查结果 self.timer QTimer() self.timer.timeout.connect(self.check_result) self.timer.start(500) # 每500ms检查一次 def check_result(self): # 检查 output_result.mat 是否存在且非空 p a hrefhttps://download.csdn.net/download/hjuihui/20028395 stylecolor:#ec7500;font-size:14px; 本文还有配套的精品资源点击获取 /a img altmenu-r.4af5f7ec.gif srchttps://csdnimg.cn/release/wenkucmsfe/public/img/menu-r.4af5f7ec.gif stylewidth:16px;margin-left:4px;vertical-align:text-bottom;cursor:text; /p