[Matlab]錯誤使用 handle.handle/get對象無效或已刪除

      以前沒接觸過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的值還是上一次計算特徵時的表格,然而此時上一次計算的表格已經在重新生成表格時被刪除,最終導致了保存表格出錯。




找到了原因就好解決了,重新new表格之後對handles進行保存,再將handles以參數的形式傳入@uitableCellSelection_Callback函數。在保存表格@ saveTable_Callback回調函數傳入的handles也是最新的表格。


解決方案如下:(修改後的代碼)
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});
...






發佈了34 篇原創文章 · 獲贊 39 · 訪問量 21萬+
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章