前言
接觸圖形界面已有一段時間,學習過python tkinter ,Pyq5學習一點,到最近由於課程matlab 作業的需要,摸索GUI操作。感覺各種東西在腦袋裏混成一團漿水。說實話,老師課上基本沒講什麼,大部分時間都是度娘和各種博客胡亂摸索了一通,總覺得查找的資料有點多,所以想綜合下各方資料,同時也給學習一些參考。
內容
課程作業的其中一項內容:製作gui界面,可以選取文件夾,將裏面的所有文件名都展示在listbox內;雙擊文件名,會顯示圖片,如果不是圖片,會彈出提示。
1.step 圖形界面的搭建
命令窗口 輸入 guide 進入圖形界面搭建。 左手邊的按鍵,自己全部點一下就知道是什麼樣有什麼功能。另外說一點就是,雙擊 控件 進入屬性設置
以下就是我構建的一個圖形界面的初始界面
2.step 功能實現。
首先分析怎麼實現。
(1)打開文件夾:獲取選擇的文件夾路徑,然後獲取該路徑下的所有的文件名,將文件名傳給listbox顯示出來。
(2)對於listbox 獲取雙擊對象的文本內容,對文本進行判斷,是圖片就顯示,否則出現報錯信息
(3)清空 清空所有的輸入,重置初始界面
分析完之後,先實現第一個功能。
(1)右鍵“打開文件夾”選擇回調,進入回調函數設置。
語法:
- if …else…end(一定要用end來結束)
- for i=a:b do something end(一定要用end來結束)
- % 該行都是註釋
% --- Executes on button press in pushbutton1.
function pushbutton1_Callback(hObject, eventdata, handles)
% hObject handle to pushbutton1 (see GCBO)
% eventdata reserved - to be defined in a future version of MATLAB
% handles structure with handles and user data (see GUIDATA)
handles.filepath = uigetdir('*.*','請選擇文件夾') %得到了文件夾的路徑
if handles.filepath %如果獲得文件夾路徑
filelist=dir(handles.filepath)
%獲得文件夾下的所有文件 是一個6x1的struct結構。得到到filelist.name屬性下獲得的前兩個是 ./ ../ 需要從第三個開始取
sizeof=size(filelist); % 總數-2就是子文件數量
len=sizeof(1);%得到個數
handles.list=cell(1,len-2)
%將子文件名內容保存到handles 下的list屬性下,這樣就能跨函數來調用數據。這裏是以胞組的形式保存,因爲每個文件名的字符串個數都不一樣(這裏踩過幾次坑,每次就想到了python裏的列表)
%遍歷每個存儲的內容,從3開始取。
%matlab的索引是從1開始的(取第幾個就用數字幾),python的索引是從0開始的,是不同的
for i=3:len
handles.list{1,i-2}=filelist(i).name %獲得字符串的文件列表 胞組要用{} 花括號來索引
end
set(handles.listbox1,'string',handles.list) %列表框文件顯示,整個胞組傳進入
set(handles.text4,'string',handles.filepath) %同時顯示當前選擇的文件路徑
%保存數據(這條命令要記住)
guidata(hObject,handles)
end
小總結:
- 1.用一個變量 來接收 dir ()返回值時是一個 struct 結構體,這和沒有變量接收打印出來的dir() 內容很不一樣。
- 2.其次接收後要獲取文件列表要從第三個開始取 ,用cell存起來。
- 3.取cell內容要用{} 花括號。
(如果有更加優化的寫法,可以在討論區艾特我,新手上車,代碼效率可能不高) - 4.關於listbox 存儲的類型驗證
MATLAB GUI 之 列表框 屬性 ‘string’ 元胞存儲
listbox 獲值說明
GUI listbox的用法
(2)listbox的響應
右鍵該控件 選擇回調進入
語法: try…catch exception …end 捕獲異常,進行一個簡單的異常處理
是通過捕獲異常來控制 提示框 的輸出
% --- Executes on selection change in listbox1.
function listbox1_Callback(hObject, eventdata, handles)
% hObject handle to listbox1 (see GCBO)
% eventdata reserved - to be defined in a future version of MATLAB
% handles structure with handles and user data (see GUIDATA)
% Hints: contents = cellstr(get(hObject,'String')) returns listbox1 contents as cell array
% contents{get(hObject,'Value')} returns selected item from listbox1
global clik
set=get(gcf,'selectiontype');%獲取鼠標按鍵類型,因爲是雙擊
if strcmp(set,'open')
%清空之前顯示的圖片
if clik
axes(handles.axes2)
cla()%清除畫布
end
num=get(handles.listbox1,'value')%直接得到列表框的文本,這裏要用'value'來獲取 點擊的項數 ,用‘string’獲取的是整個胞組內容。當時上課漏了這個細節,絕望了一個下午。
%判斷是否是圖片
all=get(handles.listbox1,'string') %得到所有的文本內容
content=all(num) %取點擊的對象 的文本
assignin('base','content',content) %使用assignin() 可以在運行的時候,在工作區裏面查看改變量輸出(十分好用的一個技巧),比直接輸出還好,可以看到變量的結構信息
content=content{1,1} %上面獲得是個胞組,所以要轉換變成char 類型
try
result=regexpi(content,'.(jpg|png|jpeg)','match') %正則匹配
%matlab 打開的圖片格式還有其他,可以在上面
result=result{1,1}%如果能夠轉,說明是圖片,而不會報錯(這裏是引發異常的關鍵)
%我在這裏用異常的原因是因爲之前我獲取的img_path是胞組類型。後來不知怎麼又變成了char類型。所以預防了這種玄學的情況,我才用了異常處理(如果有知道什麼原因導致可以在討論區回覆我)
try
img_path=strcat(handles.filepath,'\',content) %路徑拼接
assignin('base','img_path',img_path)%監控信息 是個胞組(就是通過這裏來監控img_path的類型,類型會害死人的)
% img_path=img_path;
axes(handles.axes2);
image=imread(img_path);
catch exception
img_path=img_path{1,1};
image=imread(img_path);
end
imshow(image)
clik=clik+1%只有執行完纔算有效(我在上面是通過clik來控制是否清除)
assignin('base','clik',clik)
catch exception
warndlg('這不是圖片,無法顯示','warning string')
end
end
小總結:
1.正則匹配的內容:
Matlab正則表達式(遞歸、匹配上下文等)
圖片、視頻文件、音樂文件的正則表達式
關於matlab 三個正則表達式函數的具體說明
matlab正則表達式
- regexp——用於對字符串進行查找,大小寫敏感;
- regexpi——用於對字符串進行查找,大小寫不敏感;
- regexprep——用於對字符串進行查找並替換。
2.有一點我不是用的很好的就是全局變量的聲明,我在進入主頁面開始的時候聲明瞭global 變量,但是到這裏還是會報錯,所以我又在這裏又聲明瞭一次全局變量。老師講課的建議是她很少用global來聲明,都是在handles 下新建一個屬性來保存值的。
(3)清空部分
% --- Executes on button press in pushbutton2.
function pushbutton2_Callback(hObject, eventdata, handles)
% hObject handle to pushbutton2 (see GCBO)
% eventdata reserved - to be defined in a future version of MATLAB
% handles structure with handles and user data (see GUIDATA)
global clik
set(handles.listbox1,'string',[]) %設置空
set(handles.text4,'string',[])
if clik
% axes(handles.axes2)
% cla()%清除畫布
% set(handles.axes2,'Color','w')
delete(allchild(handles.axes2))
set(handles.axes2,'Color','w')
end
清空部分有兩種做法:
-
axes(handles.axes2) cla()%清除畫布 set(handles.axes2,'Color','w')
-
delete(allchild(handles.axes2)) set(handles.axes2,'Color','w')
但是儘管用了set設置,背景色還是和主頁面一致,沒有變成白色(如果有什麼方法可以設置,可以在討論區留下你的方法,十分感謝)
最終效果
如果有什麼好的想法,可以改進的地方,歡迎在討論區留下你們的留言~