MATLAB GUI 纯代码编写
以土木学生的角度写的代码,Matlab 虽然有GUIDE来写交互界面,但是我觉得自己写代码出来的才更加舒服;只学过Python的 Tkinter 库,还没找到用matlab数据处理,用其它语言写GUI的解决方案,欢迎和我探讨。一下为我学习的笔记,和大家分享。
首先,编写GUI参考的书籍是《MATLAB GUI设计学习手记》/罗华飞编著,——北京:北京航空航天大学出版社,2009.8
根据学 Tkinter 的经验,写GUI主要实现一下功能:
- 菜单(Menu)
- 按钮(Button)
- 数据可视化
- 事件
主要难点:
- 数据传递
- 代码的健壮性
- 事件
相对于MATLAB 的GUI来说,实现这些功能是从各个对象,子对象,属性的组合,一下是我对GUI的重新分类:
父对象主要包括:
- 系统(root)
- 图形窗口(figure)
- 坐标轴(Axes)
- 界面功能区(UI)
子对象主要包括:
- 菜单(uimenu)
- 右键菜单(uicontextmenu)
- 控件(uicontrol)
- 工具栏(uitoolbar)
- 面板(uipanel)
- 表格(uitable)
- 对话框(dialog)
入门的时候,需要知道父对象有哪些子对象,如何查看他们的属性,用好get(),set()两个函数;
我开始写的时候:
【注】我的思路是创建一个对象,设置它的属性,便于理解,不断更新对象的外貌
ToggleButton = uicontrol();
set(ToggleButton,'string','切换按钮');
set(ToggleButton,'Style','togglebutton');
set(ToggleButton,'Units','normalized');
set(ToggleButton,'Position',[0.15,0.9,0.1,0.05]);
优化后:
【注】已经构思完成才写代码
ToggleButton = uicontrol(...
'string','切换按钮',...
'Style','togglebutton',...
'Units','normalized',...
'Position',[0.15,0.9,0.1,0.05]);
回调函数的编写,虽然一个m文件有一个主函数,多个子函数构成,文件内子函数之间可以相互调用,但是在其他文件外只能调用主函数。(待解决,把所有回调函数写在一个m文件里,减少文件数量)
一下是我编写的常用功能界面:
主菜单可下拉,右键菜单
GU界面的代码如下:
%----------- 纯编程语言编写MatlabGUI ------------------%
% 创建一个空白窗口
h = figure();
% 设置窗口属性
set(h,'Color',[0.9,0.9,0.9]);
set(h,'MenuBar','none');
% set(gcf,'Position',get(0,'screensize'));
set(h,'Name','Operator of Seismic');
%{
1. ---创建菜单(uimenu)
%}
% 创建一级菜单
Menu1 = uimenu(h,'label','File','Position',1);
Menu2 = uimenu(h,'label','Edit','Position',2);
Menu3 = uimenu(h,'label','Wave','Position',3);
Menu4 = uimenu(h,'label','Operator','Position',4);
Menu5 = uimenu(h,'label','Draw','Position',5);
Menu6 = uimenu(h,'label','Output','Position',6);
% 创建二级菜单
% File
uimenu(Menu1,'label','Open','Position',1);
uimenu(Menu1,'label','Close','Position',2);
uimenu(Menu1,'label','Exit','Position',3);
% Edit
uimenu(Menu2,'label','Copy','Position',1);
uimenu(Menu2,'label','Cut','Position',2);
uimenu(Menu2,'label','Paste','Position',3);
% Wave
uimenu(Menu3,'label','滤波','Position',1);
uimenu(Menu3,'label','插值','Position',2);
uimenu(Menu3,'label','抽希','Position',3);
uimenu(Menu3,'label','积分','Position',4);
% Operator
uimenu(Menu4,'label','加速度-高','Position',1);
uimenu(Menu4,'label','加速度-多','Position',2);
uimenu(Menu4,'label','位移-高','Position',3);
uimenu(Menu4,'label','位移-多','Position',4);
% Draw
uimenu(Menu5,'label','A','Position',1);
uimenu(Menu5,'label','D','Position',2);
uimenu(Menu5,'label','V','Position',3);
%{
2. 创建右键菜单(uicontextmenu)
%}
ContextMenu = uicontextmenu;
ContextMenu1 = uimenu(ContextMenu,'label','Copy');
ContextMenu2 = uimenu(ContextMenu,'label','Cut');
ContextMenu3 = uimenu(ContextMenu,'label','Paste');
set(gcf,'uicontextmenu',ContextMenu);
%{
3. 界面控制(uicontrol)
UI对象的类型由样式(Style)决定,其中包括触控按钮,切换按钮,列表框,弹起式菜单
复选框,单选按钮,滑动条,静态文本,可编辑文本,框架;
此处的位置为相对于屏幕的大小,不是百分比
%}
% 3.1 触控按钮
PushButton = uicontrol();
set(PushButton,'string','触摸按钮');
set(PushButton,'Style','pushbutton');
set(PushButton,'Units','normalized');
set(PushButton,'Position',[0.01,0.9,0.1,0.05]);
set(PushButton,'Callback','TestFcn');
% 3.2 切换按钮
ToggleButton = uicontrol(...
'string','切换按钮',...
'Style','togglebutton',...
'Units','normalized',...
'Position',[0.15,0.9,0.1,0.05]);
% ToggleButton = uicontrol();
% set(ToggleButton,'string','切换按钮');
% set(ToggleButton,'Style','togglebutton');
% set(ToggleButton,'Units','normalized');
% set(ToggleButton,'Position',[0.15,0.9,0.1,0.05]);
% 3.3 列表框
ListBox = uicontrol();
ListData = {'列表框1','列表框2','列表框3','列表框4'}; % 使用数组定义列选项
set(ListBox,'string',ListData);
set(ListBox,'Style','listbox');
set(ListBox,'Units','normalized');
set(ListBox,'Position',[0.3,0.7,0.2,0.3]);
% 3.4 弹起式菜单
PopMenu = uicontrol();
set(PopMenu,'string','弹起式菜单');
set(PopMenu,'Style','popupmenu');
set(PopMenu,'Units','normalized');
set(PopMenu,'Position',[0.6,0.9,0.2,0.05]);
% 3.5 复选框
CheckBox = uicontrol();
set(CheckBox,'string','复选框');
set(CheckBox,'Style','checkbox');
set(CheckBox,'Units','normalized');
set(CheckBox,'Position',[0.01,0.8,0.1,0.05]);
% 3.6 单选按钮
RedioButton = uicontrol();
set(RedioButton,'string','单选按钮');
set(RedioButton,'Style','radiobutton');
set(RedioButton,'Units','normalized');
set(RedioButton,'Position',[0.15,0.8,0.1,0.05]);
% 3.7 滑动条
Sliders = uicontrol();
set(Sliders,'string','滑动条');
set(Sliders,'Style','slider');
set(Sliders,'Units','normalized');
set(Sliders,'Position',[0.6,0.8,0.3,0.05]);
set(Sliders,'Max',100,'Min',0,'Value',20); % 设置滑动值得范围
% 3.8 静态文本
StaticText = uicontrol();
set(StaticText,'string','静态文本');
set(StaticText,'Style','text');
set(StaticText,'Units','normalized');
set(StaticText,'Position',[0.01,0.6,0.1,0.05]);
% 3.9 可编辑文本
EditText = uicontrol();
set(EditText,'string','可编辑文本');
set(EditText,'Style','edit');
set(EditText,'Units','normalized');
set(EditText,'Position',[0.15,0.6,0.15,0.05]);
% 3.10 框架
Frame = uicontrol();
set(Frame,'BackgroundColor','r');
set(Frame,'Style','frame');
set(Frame,'Units','normalized');
set(Frame,'Position',[0.6,0.6,0.15,0.15]);
%{
4. 可视化表格
%}
Table = uitable();
set(Table,'Units','normalized');
set(Table,'Position',[0.01,0.3,0.4,0.3]);
%{
5. 按钮组和面板
%}
Panel = uipanel();
set(Panel,'Position',[0.5,0.3,0.4,0.3]);
set(Panel,'Title','面板');
回调函数如下:文件名(TestFcn.m)
调用回调函数在GUI代码的第70行,以按钮为例。
%-----------回调函数的编写------------%
%--1.主函数
function TestFcn
h =dialog('name','回调函数','units','normalized','position',[0.4,0.4,0.3,0.2]);
uicontrol(...
h,'Style',...
'text','Units',...
'normal','String',...
'一个回调函数的测试',...
'Position',[0.3,0.4,0.4,0.2],...
'Fontsize',15);
end
% 可以在主函数中写多个功能函数,但是只能被主函数和其它功能函数调用