본문으로 바로가기

[MATLAB 연재] 16. GUI - 종합예제

category Software/MATLAB 2010.04.29 11:48

본 강좌에 사용되는 MATLAB은 버젼7.9.0 (R2009b)을 대상으로 합니다.

폼나는 예제하나 만들어 보자 !

이제껏 몇 회에 걸쳐서 GUI환경의 프로그램에 대해 이야기 했습니다. 지금까지의 연재 내용을 가지고 폼나는 뭔가를 한번 해봐야겠네요^^. 

이걸 만드는 거죠. 위에 보이다시피 진폭, 주파수, 위상차를 입력하면 그래프를 그리는 겁니다. 그냥 그리면 폼이 안나니까...^^ 한번 그리고, 또 AddFunction이라는 버튼을 누르면 '+'로 또 그리는 걸로 하죠. 괜찮겠는데요...^^

저렇게 그려줍니다. 또 다른 함수를 만들어서 AddFuncion을 눌러주면

저렇게 그려주는 거죠^^, 입력했던 수식도 글자로 나오고. 그림도 그리는....ㅋㅋ^^

GUIDE에서 화면 구성 및 태그, 속성 결정 !

일단 화면 구성 해야겠죠.

저렇게 EditBox 7개와 Axes 1개, sin과 cos을 결정할 PopMenu 1개와 Pushbuttion 1개를 배치합니다. 

이제는 프로그램이 조금 복잡해지니까 tag들을 변경해서 알기 쉽게 두도록 하죠. 윗 줄에 각 edit text들의 tag를 표시해두었습니다.

그리고, Popup Menu의 tag도 잡아주구요

그 다음 edit text 2개의 tag도 잡습니다. 그리고, Terms는 사용자에게 입력받을 것이 아니기때문에, inspector window에서 enable이라는 속성을 찾아서 off로 바꿔줍니다. 그러면, 프로그램에서는 string 속성을 만져서 글자를 바꿔줄 수 있지만, 사용자가 편집하지는 못합니다. 

그 다음 수식의 결과가 나오는 edit text의 태그와 enable 속성입니다. 앗.. 오타네요. Tag : dispEqu 입니다.

마찬가지로, 혹시 모를 에러코드를 표현할  edit text입니다. 나머지 언급하지 않은 것은 모두 static text입니다.

Call Back 함수 작성하기 !

사용자가 입력을 완료하고 Push Button을 누르면 그리도록 할 것이니 Push Button의 CallBack함수에 모든 코드를 위치시키겠습니다.

먼저, edit text, popup menu에서 이미 언급한데로 변수와 함수종류를 받아(get)옵니다. 

이게 기본 뼈대인데요. 제일 첫 줄은 sin이나 cos이 더해지는데 각 항 별로 시간축의 범위가 다르면 이상하겠죠.? 그래서 한번 입력하고 나면, 다시 종료시간을 수정할 수 없도록, enable속성을 off로 강제로 두는 겁니다. 그리고, 그림은 항수(많으면 귀찮으니까)가 4개이하로, 진폭과 주파수가 '0'이 아닐때, 그리도록 하는 것입니다. 나머지 상황은 에러코드로 정의해둡니다. 그렇다면, MAIN CODE라고 되어있는 부분과 Error CODE라고 되어있는 부분만 건드리면 되겠네요.

항수를 체크하기 위해 count를 세는 것입니다. 그리고, 그 다음줄은 화면에 항 수를 넣어두구요. 그리고, 사용자의 입력 수식의 이전결과가 dispEqu 태그의 edit text에 있을테니 그걸 가져 오는 겁니다. 만약 첫 항이라면, Nothing이라는 값이 있을테니, 그런 경우는 공란(' ')으로 두도록 되어있구요. 그리고 뒤에 '+'기호를 넣어두는것이죠. 역시 설명한 적이 있는 eval 명령을 이용해서 전체 수식을 만드는 부분입니다. 이 코드 그 다음에는

실제 그림을 그리는 부분이 들어갑니다. subs명령이 보이는데요. 이는 문자열중에서 문자 't;를 변수 t로 변환시켜줍니다. 따옴표(')가 있고 없고의 차이죠^^. 그러면, y에 바로 수식의 결과값이 저장되는 거죠. 나머지는 그려주는 건데요. 'ylim'속성에 1.1을 곱한 이유는 보기 편하게 10%의 여유를 둔 것입니다.

그리고, 에러코드는 해당하는 순서대로 문자열로 저장해두고 호출하는 방식입니다. 이렇게 하면 끝났네요^^

fig 화일은 

guiTestV2.fig

이구요. m화일은

guiTestV2.m

입니다.

음... m화일의 전체코드는

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

Amp = str2double(get(handles.Amp, 'String'));
Freq = str2double(get(handles.freq, 'String'));
PhaseShift = str2double(get(handles.PhaseShift, 'String'));
endTime = str2double(get(handles.endTime, 'String'));
count = str2double(get(handles.count, 'String'));
contents = cellstr(get(handles.targetFunc, 'String'));
TargetFunc = contents{get(handles.targetFunc, 'Value')};

set(handles.endTime, 'enable', 'off')

if (count>=0)&&(count<=3)&&(Amp~=0)&&(Freq~=0)
    errorCode = 1;
    count = count + 1;
    set(handles.count, 'String', count);
    preEqu = get(handles.dispEqu, 'String');
    if strcmp(preEqu, 'Nothing')
        preEqu = '';
    else
        preEqu = eval([' '' ' preEqu ' + '' ']);
    end
    reEqu = eval([''' ' preEqu '' num2str(Amp) '*' TargetFunc '(2*pi*' num2str(Freq) '*t +' num2str(PhaseShift) ') ''']);
    set(handles.dispEqu, 'String', reEqu);


    t = 0:0.01:endTime;
    y = subs(reEqu, 't', t, 0);

    plot(handles.axes1, t, y)
    set(handles.axes1, 'xlim', [0 endTime], 'ylim', [min(y) max(y)]*1.1, 'xgrid', 'on', 'ygrid', 'on')

elseif count>3
    errorCode = 2;
elseif Amp==0
    errorCode = 3;
elseif Freq==0
    errorCode = 4;
end

ErrorMsg = {{'Correct Expression'}
    {'Too many terms'}
    {'Amplitute is ''0'''}
    {'Frequency is ''0'''}};

set(handles.ErrorCode, 'String', ErrorMsg{errorCode});

입니다.^^

이제 길었던 MATLAB 기초연재를 마무리 합니다. 뭐 어차피 제 블로그의 MATLAB 카테고리에서는 계속 MATLAB이야기를 하겠지만 말이죠^^.

신고