某个天朗气清的下午,老师给我布置了一个Matlab GUI 界面设计的任务,然后欢天喜地回家结婚去了,留我在美好的假期里继续孤零零地在学校里耕耘。好的,在此先祝贺老师新婚快乐,百年好合。然后咱们开始从零开始,一边学,一边做。
作为一个GUI小白,当然不能盲目瞎胡来。我们首先要了解gui设计的一些基本的知识,比如如何添加控件、修改控件名称、如何定义变量、获取变量、怎么传递变量等等。这些在网络上都可以搜的到,在此不多赘述了。这边奉上几个小链接,都是很好的学习资料,大佬们总结的太好了。
1.matlab如何创建图形用户界面gui? 上面这个例子可以让我们学会一些基本的操作。如何设置静态文本、动态文本、坐标轴什么的。可以自己尝试做个简单的小程序玩一下。好的,我做了个1+1=2. 挺简单的是吧!(smile~)后来改了一次函数什么的,总之第一天花一点时间先熟悉一下界面。
2.MATLAB GUI界面编程——一些细节问题 第二个例子,这篇博文也写的很清楚。不过我要强推的是这篇文章最后推荐的另一篇文章。该网页内二楼提供了一个PDF文档,是一个很完整的界面编程实例。再次上链接,我是个稳妥的搬运工~一个实例搞定MATLAB界面编程.pdf 。
又花了一天时间,把这个实例好好学习了一下,在自己的Matlab 里运行成功了,我的Matlab版本是R2016b。运行成功以后,也重复看了好几遍这个程序,理解程序里对变量的定义和传递(这个蛮重要的)。关于这个实例的内容在此不提,跟着一步步做就可以了。
整个做完这一整个例子,我开始信心满满地(划掉——)投身老师给我的任务。主要分为以下几个步骤: (1)规定自己的设计目标。比如导入数据、输入哪些参数、输出哪些参数、要显示什么图像、哪些数据要保存以及保存成什么类型的数据等等,这些都要提前想好并列出清单。 (2)界面设计排版。鉴于之前有不断被甲方爸爸要求做PPT、改PPT做了好长一段时间的辛酸经历,我觉得界面设计的美观程度还是蛮重要的。于是我参照了一些和我要做的任务类似的GUI界面,对我的GUI界面进行初步排版设计。 (3)编写程序。我给自己的程序分了几个阶段:第一步是数据的打开、关闭;第二步,主程序的编写;第三步,输出结果的保存、导出;第四步,处理一些细节问题和小错误。
emmm,整个过程大概花了整整三天的时间,一边报错,一边修改,可算是调试成功并完成了,真是万幸。下面记录一些自己在学习过程中遇到的问题和部分代码。
1、数据的打开,读取 (1)设计目标:点击“打开”按钮,选择txt文件,读取txt文件里的数据。
function m_file_open_Callback(hObject, eventdata, handles)
% hObject handle to m_file_open (see GCBO)
% eventdata reserved - to be defined in a future version of MATLAB
% handles structure with handles and user data (see GUIDATA)
% filepath = uigetdir('*.*','请选择文件夹');
[filename, pathname] = uigetfile( ...
{'*.bmp;*.jpg;*.png;*.jpeg;*.txt', 'Image Files (*.bmp, *.jpg, *.png,*.jpeg,*.txt)'; ...
'*.*', 'All Files (*.*)'}, ...
'选择txt文件');
if isequal(filename,0) || isequal(pathname,0) % 处理取消打开文件的情况
return;
end
filepath=pathname;%
handles.filepath=filepath;
fid=[pathname filename];%将文件名和目录名组合成一个完整的路径,获取txt文本
fid1=fopen(fid);
% 读入 txt 文本信息
data1=[];
s1=0;
while ~feof(fid1)%~feof表示若未读到文件末尾则继续循环
s1=s1+1;
tline1=fgetl(fid1);%fgetl 按行读取
idx=strfind(tline1,',');%查找 , 字符串
if ~isempty(idx) % ~isempty判断是否为空,是为0,否为1
if strcmp(tline1(1),'"') %strcmp比较字符串,如果是和 " 一样的,返回1
data1(s1,1)=str2num(tline1(2:idx(1)-1));
else
data1(s1,1)=str2num(tline1(1:idx(1)-1));
end
str1=tline1(idx(1)+1:idx(2)-1);%查找时间信息所在的位置
data1(s1,2)=datenum(str1); % time
for i=4:14
data1(s1,i)=str2num(tline1(idx(i-1)+1:idx(i)-1));%依次存储第3,4,5...14个信息
end
end
end
fclose(fid1);
% setappdata(handles.figure_current,'data1',data1);
handles.data1=data1;
guidata(hObject, handles);
2、设置变量中遇到的一些问题(主要是针对输入变量的) 设计目标:输入变量既有自己的默认值也可以手动编辑,在点击“恢复默认值”按钮时,可以恢复到默认值状态。另外设置“清空”按钮,点击“清空”按钮,可以对可编辑文本框进行清空,需要自己手动输入数值。 下面是我设置的几个按钮;
(1)可编辑文本变量的输入。 在主程序的“运行”按钮的callback回调函数下,在function m_file_run_Callback(hObject, eventdata, handles)下输入:
m_image_a=str2double(get(handles.m_image_a'String'));
m_image_b=str2double(get(handles.m_image_b,'String'));
这样就可以获得编辑框内的数字了。m_image_a是设置的对应编辑文本的Tag值。顺便提一下,回调函数的查看和设置都是可以自动定位的,只要我们在设计界面内的控件上 右键 > 查看回调,就可以选择我们需要的回调函数了。 (2)可编辑文本的初始化或设置默认值。 我想别人打开我的界面的时候,点击“恢复默认值”按钮,就可以让对应的可编辑文本框m_image_a里显示我想要的内容。那我们就需要在可编辑文本框m_image_a的CreateFcn回调函数下进行定义。在function m_image_a_CreateFcn(hObject, eventdata, handles) 的最后加上
set(hObject,'string','3');
这样我们就能够将Tag值为m_image_a的可编辑文本框的默认值设置好啦,我设置的是3。注意在一个界面里,每个控件都有自己唯一的Tag名称,那就是他们的大名,不能有重复的两个Tag值。还有设置某个控件的Tag值,名称中间不要加空格,否则是无效滴。 (3)可编辑文本的清空。 这个步骤分为两步, 第一步,在可编辑文本m_image_a的KeyPressFcn回调函数 function m_image_a_KeyPressFcn(hObject, eventdata, handles)后加上如下代码
set(hObject,'string','','Enable','on');
uicontrol(hObject);
第二步,在“清空”按钮的callback回调函数function m_image_clear_Callback(hObject, eventdata, handles)后加上如下代码
feval(@m_image_a_KeyPressFcn,handles.m_image_a,eventdata,handles);
feval函数可以用来调用其他函数的功能。
(4)静态文本变量的输出 这个静态文本的变量呢,我们是不能自己编辑的,那我们是通过其他变量计算得到的,然后显示在静态文本框内。那我们在“运行”按钮的callbak回调函数下继续编辑
m_image_c=m_image_a+m_image_b; %m_image_a 和 m_image_b都是可编辑文本变量,m_image_c 是静态文本变量
set(handles.m_image_c,'String',num2str(m_image_c,'%.2f')); % 保留两位小数
m_image_a 和 m_image_b都是可编辑文本变量,m_image_c 是静态文本变量。
(5)静态文本变量的清空 和可编辑文本变量的清空类似,同样咱们分为两步。 第一步,在静态文本m_image_c的CreateFcn回调函数 function m_image_c_CreateFcn(hObject, eventdata, handles) 后面加上,
set(hObject,'string','');
第二步,在“清空”按钮的callback回调函数function m_image_clear_Callback(hObject, eventdata, handles)后加上如下代码
feval(@m_image_c_CreateFcn,handles.m_image_c,eventdata,handles);
那像这样咱们在点击“清空”按钮之后,就可以把可编辑文本和静态文本都清空空啦! (6)坐标轴的清空 我的运行程序完成以后,是要显示图形的。运行程序以后,就会出图,那么如果我想清空数据,重新运行,那就要把界面上的数据和图都清除干净。清除图形我用的是下面这个方法,同样是在“清除”按钮的callback回调函数下进行编辑,加上
try
delete(allchild(handles.axes_test));
end
axes_test是要清除图形对应的坐标轴Tag值。
(7)其他变量的定义,输出 如果在程序运行的过程中,我们需要定义其他的一些变量,后期需要导出这些变量的值的话,我们需要对其进行定义。在“运行”按钮的callback回调函数下,进行编辑,参考如下
d=8;
handles.d=d;
set(handles.m_image_d,'String',num2str(d,'%.2f'));
guidata(hObject, handles);
3、输出数据的保存、导出
【下次再写。。。。下班时间到了。。。】
|