以前沒接觸過Matlab,最近手上接到個項目,遇到一個問題各種谷歌沒找到答案,經過兩個星期努力,最終還是自己耐心輸出log找到了問題所在。
UI部分如下圖:
正常流程:
計算——將數據顯示在表格中——保存表格
觸發錯誤流程:
計算特徵之後,對錶格進行選中(uitableCellSelection_Callback回調),再保存表格出錯。
報錯信息如下:
=======================================
錯誤使用 handle.handle/get
對象無效或已刪除。
出錯textureAnalysis>saveTable_Callback (line 861)
cloumnName=get(handles.table,'ColumnName');
出錯 gui_mainfcn (line 95)
feval(varargin{:});
出錯 textureAnalysis (line43)
gui_mainfcn(gui_State, varargin{:});
出錯@(hObject,eventdata)textureAnalysis('saveTable_Callback',hObject,eventdata,guidata(hObject))
Error while evaluatinguicontrol Callback
相關函數的回調函數截取部分代碼如下:
function featureCalculation_Callback(hObject, eventdata, handles) % 特徵計算回調函數
% hObject handle to featureCalculation (see GCBO)
% eventdata reserved - to be defined in a future version of MATLAB
% handles structure with handles and user data (see GUIDATA)
...
if ~isfield(handles,'table')
handles.table = uitable(handles.uipanelTextureTable,'units','normalized', 'Tag','filterTable', 'ColumnName',ColumnName,'RowName',RowName,...
'data',data,'FontSize',12,'CellSelectionCallback',{@uitableCellSelection_Callback,handles});
else
delete(findobj(gcf,'tag','filterTable'));
handles.table = uitable(handles.uipanelTextureTable,'units','normalized','position','Tag','filterTable', 'ColumnName',ColumnName,'RowName',RowName,...
'data',data,'FontSize',12,'CellSelectionCallback',{@uitableCellSelection_Callback,handles});
end...
function saveTable_Callback(hObject, eventdata, handles) % 保存表格回調函數
% hObject handle to saveTable (see GCBO)
% eventdata reserved - to be defined in a future version of MATLAB
% handles structure with handles and user data (see GUIDATA)
…
cloumnName=get(handles.table,'ColumnName'); % 此行出錯
rowName= get(handles.table,'RowName');
保存表格
…
function uitableCellSelection_Callback(hObject,eventdata,handles) % 表格Cell選中回調事件
%= guidata(hObject);
rawNum= eventdata.Indices(1);
switch(rawNum)
case 2
handles.showEnhanceData = handles.transferFilterData1;
case 3
handles.showEnhanceData = handles.transferFilterData2;
case 4
handles.showEnhanceData = handles.transferFilterData3;
end
guidata(hObject,handles);
showImage(handles);
一開始老覺得是表格選中那裏出的問題,因爲剛接觸Matlab才兩個星期,對句柄這些東西還不是很熟悉,只能靠猜,把uitableCellSelection_Callback中的guidata註釋掉就不會報錯了,一直以爲是這個地方出的問題,但是我在這個函數修改了handles的變量,必須使用它保存。就因爲這個點一直糾結了一個多星期問題都沒解決。
今天想靜下心來找到根本原因,然後就對handles.table的值進行輸出觀察。
1.在正常保存的情況,handles.table: 406.0072(控件是個變化的值,此處截取輸出測試時的值),在計算後和保存時都是一樣的,所以能成功的保存。
2.再按出錯的流程走一遍,此時計算完特徵後handles.table: 406.0073,[!!!]注意此處值增加了,說明控件已經不是計算前的那個table了,已經重新new了。然後再選中表格回調第一句輸出handles.table: 406.0072,那說明回調函數傳進來的handles還是上一次計算的表格,所以問題並不是出在選中表格的回調函數中,而是在上一層計算函數中就有問題了。
這個時候突然想起來,在每次計算的時候因爲計算結果可能不同,所以就把上一次計算的表格直接刪除了,又重新new了一個表格。然後回到代碼中(如下圖)發現在new表格的同時聲明瞭回調函數,並以handles爲形參傳入。在Matlab中對handles結構體中的數據進行修改,需要用guidata語句來進行回寫保存。在代碼中重新生成了一個表格,已經對handles.table值進行了覆蓋,但在這條語句中還沒有保存,就將handles傳給了@uitableCellSelection_Callback回調函數,所以在該函數開頭輸出handles會發現handles.table的值還是上一次計算特徵時的表格,然而此時上一次計算的表格已經在重新生成表格時被刪除,最終導致了保存表格出錯。
解決方案如下:(修改後的代碼)
function featureCalculation_Callback(hObject, eventdata, handles) % 特徵計算回調函數
% hObject handle to featureCalculation (see GCBO)
% eventdata reserved - to be defined in a future version of MATLAB
% handles structure with handles and user data (see GUIDATA)
...
if ~isfield(handles,'table')
handles.table = uitable(handles.uipanelTextureTable,'Units','normalized','Position', 'Tag','filterTable', 'ColumnName',ColumnName,'RowName',RowName,'Data',data,'FontSize',12);
else
delete(findobj(gcf,'tag','filterTable'));
handles.table=uitable(handles.uipanelTextureTable,'Units','normalized','Position',
'Tag','filterTable', 'ColumnName',ColumnName,'RowName',RowName,'Data',data,'FontSize',12);
end
guidata(hObject,handles);
set(handles.table, 'CellSelectionCallback',{@uitableCellSelection_Callback,handles});
...