Simulink建模助手系列-进阶1【界面化并集成到Simulink的右键菜单】

Simulink建模助手系列-进阶1

  • [0. 前言](#0. 前言)
  • [1. 主界面的实现](#1. 主界面的实现)
    • [1.1 实现思路](#1.1 实现思路)
    • [1.2 示例代码](#1.2 示例代码)
  • [2. 集成到Simulink的右键菜单](#2. 集成到Simulink的右键菜单)
  • 系列文章
    • [- 基础篇:](#- 基础篇:)
    • [- 进阶篇:](#- 进阶篇:)

0. 前言

之前的文章中介绍了一些提高建模效率的脚本代码,为了更方便地使用这些脚本,最好还是将其界面化,并且通过界面化可以提升与用户的交互,从而实现一些更为复杂的功能,因此部分功能将结合界面化进行该系列的分享。为了进行区分,偏向脚本级的、较简单的功能划分到基础篇,需要配合界面实现更复杂功能的将归到进阶篇。

作为进阶篇的第一篇文章,本文主要介绍建模助手主界面的基本实现,并将其集成到Simulink的右键菜单中。

1. 主界面的实现

1.1 实现思路

主界面采用uifigure的方式构建,Matlab虽然提供了appdesigner用于Ui界面的构建和开发,不过感觉不够灵活和过于臃肿,所以本文采用纯代码的方式构建Simulink建模助手的主界面。

主界面希望尽量简洁,主要包括三个区域:菜单栏,快捷操作区,状态栏。如图1所示,菜单栏主要用于放一些特殊功能,状态栏主要用于显示一些需要保持显示的消息,快捷操作区主要用于调用简单功能脚本的按钮,如基础篇中提到的功能可以封装成这些按钮的回调函数。

图1 主界面组成

考虑到主界面需要和Simulink模块同时可见,不能被Simulink的界面遮挡,因此主界面采用置顶显示设置,不过这也导致了一些问题,有些还没有得到解决(比如消息对话框不能用msgbox,否则会被主界面遮挡,只能用uialert,这也导致自动关闭对话框的方法没能实现),后面看看有什么办法可以解决,有大神知道的也可能评论区留言提示下。

操作区的布局采用uigridlayout,往uigridlayout里添加元素时,会根据设定好的行和列依次添加,如果是顺序添加元素,可以节省些代码量。

1.2 示例代码

matlab 复制代码
function fig = app_slTool_mainUi(varargin)
    % 全局设置
    fontSize = 8;

    % 主界面
    fig = uifigure('Name','Simulink建模助手(示例)',...
        'Resize','off', ...
        'Pointer','hand', ...
        'WindowStyle','alwaysontop'); 
    bt_rows = 7; % 预设的按钮行数
    fig.Position(3:4) = [300, bt_rows*30+20];

    % 主界面布局
    ly_main = uigridlayout(fig, ...
        'RowHeight',{'1x','fit'}, ...
        'ColumnWidth',{'1x'}, ...
        'Padding',[1,1,1,1]*2);

    %% 快捷按钮区
    panel = uipanel(ly_main, ...
        'Title', '', ...
        'Fontsize', fontSize);

    ly_panel = uigridlayout(panel, ...
        'ColumnWidth', repelem({'1x'},3), ...
        'RowHeight', repelem({'1x'},7), ...
        'ColumnSpacing', 3, ...
        'RowSpacing', 3, ...
        'Padding', [3,1,3,1], ...
        'Tooltip','');
    
    % 第1行
    uibutton(ly_panel, ...
        'Text', 'Goto创建From', ...
        'ButtonPushedFcn', @cb_createFromByGoto, ...
        'Tooltip', '根据选中的Goto创建From。');

    uibutton(ly_panel, ...
        'Text', 'Goto创建Input', ...
        'ButtonPushedFcn', '', ...
        'Tooltip', '根据选中的Goto创建Input。');
    
    uibutton(ly_panel, ...
        'Text', '[预留按钮]', ...
        'ButtonPushedFcn', '', ...
        'Visible','off', ... 
        'Tooltip', '预留位置');

    % 第2行
    uibutton(ly_panel, ...
        'Text', 'From创建Goto', ...
        'ButtonPushedFcn', '', ...
        'Tooltip', '根据选中的From创建Goto。');

    uibutton(ly_panel, ...
        'Text', 'From创建Output', ...
        'ButtonPushedFcn', '', ...
        'Tooltip', '根据选中的From创建Output。');

    uibutton(ly_panel, ...
        'Text', '[预留按钮]', ...
        'ButtonPushedFcn', '', ...
        'Visible','off', ... 
        'Tooltip', '预留位置');

    % 第3行
    uibutton(ly_panel, ...
        'Text', '[预留按钮]', ...
        'ButtonPushedFcn', '', ...
        'Visible','off', ... 
        'Tooltip', '预留位置');

    uibutton(ly_panel, ...
        'Text', '[预留按钮]', ...
        'ButtonPushedFcn', '', ...
        'Visible','off', ... 
        'Tooltip', '预留位置');

    uibutton(ly_panel, ...
        'Text', '[预留按钮]', ...
        'ButtonPushedFcn', '', ...
        'Visible','off', ... 
        'Tooltip', '预留位置');

    % 第4行
    uibutton(ly_panel, ...
        'Text', '批量连线', ...
        'ButtonPushedFcn', '', ...
        'Tooltip', '选中的模块批量连线,模块已有连线时无法连接');

    uibutton(ly_panel, ...
        'Text', 'G/F对齐连线', ...
        'ButtonPushedFcn', '', ...
        'Tooltip', '将选中的Goto和From模块与其信号线对齐。');

    uibutton(ly_panel, ...
        'Text', '智能调整Sub', ...
        'ButtonPushedFcn', '', ...
        'Tooltip', '对选中的子系统调整高度,对齐输入输出。');
   
    %% 底部状态栏
    statusBar = uilabel(ly_main, ...
        'Text','就绪', ...
        'HorizontalAlignment', 'left', ...
        'Fontsize', fontSize);
    

    %% 顶部主菜单
    mHelp = uimenu(fig,'Text','帮助');
    uimenu(mHelp, ...
        'Text','关于',...
        'MenuSelectedFcn','');
end
matlab 复制代码
% 回调函数:根据Goto创建From
function cb_createFromByGoto(src,event)
    currentSystem = gcs; % 获取当前模型
    %获取选中的Goto
    selectedGotos = find_system(currentSystem, ...
        'SearchDepth', 1, ...
        'Selected', 'on', ...
        'BlockType', 'Goto');
    % 逐个创建From
    for i = 1:length(selectedGotos )
    	% 逐个获取Goto模块的信息
    	gotoPath = selectedGotos{i};
    	gotoTag = get_param(gotoPath, 'GotoTag');
    	gotoPos = get_param(gotoPath, 'Position');
    	parentPath = get_param(gotoPath,'Parent');

    	% 根据Goto的路径构建From
    	fromName = [parentPath,'/From'];
    	% 创建From模块
    	fromObj = add_block(['simulink/Signal Routing/From'], ...
            fromName, 'MakeNameUnique','on');

    	% 设置Tag
    	set_param(fromObj, 'GotoTag', gotoTag);
    	% 计算From的位置和大小
    	x_move = 20;
    	x1 = gotoPos(3)+x_move; % From在Goto的右侧
    	x2 = x1+gotoPos(3)-gotoPos(1); % From继承Goto的宽度
    	fromPos = [x1, gotoPos(2), x2, gotoPos(4)];
    	% 设置Position
    	set_param(fromObj, 'Position', fromPos);
    end
end

以上是主界面实现的基础方式,以及把根据Goto创建From的代码封装成按钮的回调函数。基础篇中介绍的脚本代码都可以封装成回调函数,填充到按钮中。如果有需要可以通过这种方式,打造专属的Simulink建模助手。

2. 集成到Simulink的右键菜单

主界面已经初具形状了,但是如何启动主界面呢?本文给出一种将其集成到Simulink的右键菜单的方法,并且能够避免重复打开多个主界面。

该方法需要创建一个名为sl_customization.m文件,并将其所在的路径添加到Matlab的搜索路径中,初次在matlab已经打开的情况下创建该文件时,添加好路径后,需要在命令行中运行sl_refresh_customizations,使新建的文件生效。

matlab 复制代码
% sl_customization.m
function sl_customization(cm)
    % 新增sl文件后刷新:运行命令 sl_refresh_customizations

    % 增加菜单
    try
        cm.addCustomMenuFcn('Simulink:ContextMenu',@getMyMenuItems);
    end
end


function schemaFcns = getMyMenuItems(callbackInfo)
    schemaFcns = {@getItem1};
end

function schema = getItem1(callbackInfo)
    schema = sl_action_schema;
    schema.label = 'sl建模助手';
    schema.callback = @run_slTool;
end

function run_slTool(callbackInfo)
    persistent h
    try
        figure(h);
    catch
        h = app_slTool_mainUi();
    end
end

成功添加后,我们可以在Simulink的右键菜单中找到主界面的启动按钮,如图2所示。

系列文章

- 基础篇:

Simulink建模助手系列-1【批量创建Goto和From】
Simulink建模助手系列-2【自动创建缺失的Goto】
Simulink建模助手系列-3【批量创建Inport和Outport】
Simulink建模助手系列-4【批量添加信号线】
Simulink建模助手系列-5【批量对齐模块】
Simulink建模助手系列-6【自动调整子系统高度和信号线】

- 进阶篇:

相关推荐
Evand J1 天前
matlab GUI制作界面的一些笔记(入门)
开发语言·笔记·matlab
dracula0001 天前
Simulink建模助手系列-6【自动调整子系统高度和信号线】
matlab
dracula0002 天前
Simulink建模助手系列-4【批量添加信号线】
matlab
dracula0002 天前
Simulink建模助手系列-5【批量对齐模块】
matlab
dracula0003 天前
Simulink建模助手系列-2【自动创建缺失的Goto】
matlab
Evand J3 天前
【UWB与IMU紧耦合定位,MATLAB例程】UWB的TOA定位方法,与IMU紧耦合,对目标轨迹定位并输出误差统计。适用于二维平面的高精度定位导航
开发语言·matlab·平面·uwb·组合导航
禁默3 天前
零基础全面掌握层次分析法(AHP):Python实现+论文加分全攻略
python·数学建模·matlab
软件算法开发3 天前
基于火烈鸟搜索算法的LSTM网络模型(FSA-LSTM)的一维时间序列预测matlab仿真
人工智能·rnn·matlab·lstm·一维时间序列预测·火烈鸟搜索算法·fsa-lstm
简简单单做算法4 天前
基于LSTM长短记忆网络模型的文本分类算法matlab仿真,对比GRU网络
matlab·分类·gru·lstm·文本分类