是的,這是預期的行爲!變量test
的範圍對每個函數都是局部的,所以您不能在一個函數中更改它,並期望更改後的值出現在另一個函數中。
這裏有幾個選項!例如,您可以使用handles
結構傳遞「全局」變量。在代碼中,你將不得不修改它,像這樣:
% --- Executes on button press in stop.
function stop_Callback(hObject, eventdata, handles)
handles.test = 0;
set(handles.display, 'String', num2str(handles.test));
guidata(hObject, handles); % Store the changed handles structure
% --- Executes on button press in start.
function run_Callback(hObject, eventdata, handles)
handles.test = 1;
while handles.test > 0
handles.test = handles.test + 1;
set(handles.display, 'String', num2str(handles.test));
guidata(hObject, handles); % stores the changed handles structure
pause(1);
handles = guidata(hObject); % updates "handles" to see the change!
end
這是一個非常標準的方法,但它有一些缺點:這是超級容易不小心遺漏更新或檢索handles
結構。此外,由於這兩個功能並行運行,它們容易受到競爭條件的影響。
第二種方法是使用global
語句。它插入容易:
% --- Executes on button press in stop.
function stop_Callback(hObject, eventdata, handles)
global test;
test = 0;
set(handles.display, 'String', num2str(test));
guidata(hObject, handles);
% --- Executes on button press in run.
function run_Callback(hObject, eventdata, handles)
global test;
test = 1;
while test > 0
test = test + 1;
set(handles.display, 'String', num2str(test));
guidata(hObject, handles);
pause(1);
end
然而,這也帶有一些缺點:現在變量test
是真正的全球化。它可以在其他腳本,函數或GUI中進行更改,因此您應該選擇比test
更獨特的名稱,並且一般要小心。另外,如果(單例)GUI在不關閉的情況下重新啓動,GUI的可視狀態,handles
結構的內容以及全局變量的內容可能會變得「不同步」。我被這兩次咬傷,所以我不再使用這種方法。
第三種方法包含變量test
應始終鏈接到GUI文本字段的事實。因此它使用display
字段中的字符串替代變量。從本質上講,這意味着使用get
,set
,str2double
和num2str
很多:
% --- Executes on button press in stop.
function stop_Callback(hObject, eventdata, handles)
set(handles.display, 'String', num2str(0));
guidata(hObject, handles);
% --- Executes on button press in start.
function run_Callback(hObject, eventdata, handles)
set(handles.display, 'String', num2str(1));
while str2double(get(handles.display, 'String')) > 0
set(handles.display, 'String', ...
num2str(str2double(get(handles.display, 'String')) + 1));
guidata(hObject, handles);
pause(1);
end
這是冗長的,但它是我在這些情況下使用。這是最健壯的解決方案,尤其是在重新啓動(單例)GUI時不首先關閉它。
第一種方法按預期工作!我之前在測試中使用過它,但我沒有意識到這一行「handles = guidata(hObject);%更新」句柄「以查看更改!」所以它不見了,所以它的行爲就像我的請求中的代碼。 謝謝! – user3548298
關於第一種和第三種方法,最有效的是什麼?我試圖爲音頻製作一個實時處理程序,我需要小心這個問題 – user3548298
我的直覺告訴我,兩種方法都非常高效 - 帶有'global'聲明的方法可能是最快的。在第一種和第三種方法之間,我猜第一種方法更快。但只有測試才能確定。實時音頻可能會非常棘手,您可能需要解決更先進的魔法。無論如何,祝你好運! –