2017-01-02 6 views
2

실행중인 버튼을 누를 때 루프에 증가하는 숫자를 표시하고 루프 중에 다른 버튼을 눌러 값을 변경하는 간단한 프로그램을 만들고 싶습니다. . 지금까지 발견 한 것을 사용하여 작성한 프로그램은 숫자를 늘리고 올바르게 표시하지만 사용하는 변수는 서로 독립적이므로 분명히 값을 0으로 재설정 할 때마다 루프가 계속됩니다. 재설정.Matlab - GUI - 다른 콜백에서 변수를 변경하여 변수 수정하기

% --- Executes on button press in stop. 
function stop_Callback(hObject, eventdata, handles) 
test = 0; 
set(handles.display, 'String', num2str(test)); 
guidata(hObject, handles); 

% --- Executes on button press in run. 
function run_Callback(hObject, eventdata, handles) 
test = 1; 
while test > 0 
    test = test + 1; 
    set(handles.display, 'String', num2str(test)); 
    guidata(hObject, handles); 
    pause(1); 
end 

이 테스트 변수를 전역 변수로 만드는 방법, 초기화 방법 및 파일에 저장해야하는 위치는 무엇입니까?

답변

1

예, 예상되는 동작입니다. 변수 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, str2doublenum2str을 사용하는 것을 의미 많은 :

% --- 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를 닫지 않고 다시 시작하는 경우 가장 강력한 솔루션입니다.

+0

첫 번째 방법은 의도 한대로 작동합니다! 실제로 테스트에서 이전에 사용했지만 그 줄을 인식하지 못했습니다 "handles = guidata (hObject); % 업데이트는"처리 "하여 변경 사항을 확인합니다!" 그래서 그것은 누락되었고 그래서 그것은 나의 요청에있는 코드처럼 행동했다. 감사합니다. – user3548298

+0

첫 번째 및 세 번째 방법은 무엇이 가장 효율적입니까? 나는 오디오를위한 실시간 처리 프로그램을 만들려고 노력하고있다. 나는 그것에 대해 조심할 필요가있다. – user3548298

+0

내 직감은 어느 방법도 굉장히 효율적이지 않다는 것을 말해 준다.'global' 문을 사용하는 방법이 아마도 가장 빠를 것이다. 첫 번째와 세 번째 방법 사이에, 나는 첫 번째 방법이 더 빠를 것이라고 생각한다. 그러나 테스트만으로 확실하게 결정할 수 있습니다. 실시간 오디오는 까다로워 질 수 있으며보다 고급스러운 마술로 해결해야 할 수도 있습니다. 어쨌든 행운을 빌어 요! –

0

변수를 전역 변수로 선언 할 수 있습니다. 이것은 할 것이다. 프로젝트가 작고 단일 M-파일에 맞는 경우

% --- 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 
0

, 당신은 nested functions를 사용하여 가장 쉽게이 문제를 해결할 수 있습니다.당신이 가이드를 사용하여 GUI를 만드는 경우

, 당신은 다음과 같은 방법으로 가장 쉽게이 작업을 수행 할 수 있습니다

    (먼저 GUI 편집에서 자동 생성 된 m-파일의 복사본을 저장해야합니다) 기능 키워드 end으로 종료되지 않은 경우
  1. 다음, m-파일
  2. 를 엽니 다 (이름이 m 파일에)
  3. 가에서 추가 end을 넣어 매우 첫 번째 함수를 제외하고, 정의 된 모든 기능에 추가 너의 m 파일의 맨 아래쪽

이렇게하면 최상위 함수에서 정의하는 모든 변수가 하위 함수 (중첩 된 함수, 콜백 임)에서 사용할 수 있습니다. 표준 Matlab 편집기는 많은 기능에 걸쳐 범위가있는 경우 변수를 다르게 강조 표시합니다.