월요일, 10월 12, 2009

Matlab으로 간단한 GUI 만들기와 Timer 연동

연구를 하는 과정에서 여러 목적으로 문제를 해결하기 위한 알고리즘을 만들려고 할 경우에, 생각한 아이디어가 의도대로 동작하는지를 확인하는 것이 필요하다. 이 때에, 다양한 입력 패턴을 알고리즘에 적용해 보거나, 파라미터 값들과 시스템 출력 등을 쉽게 확인해 보기에는 GUI를 만드는 것이 좋을 때가 많다. 그러나, MFC를 이용해 GUI를 만드는 것은 때로 매우 복잡한 작업을 필요로 할 때가 많다. 특히 다양한 수학적 알고리즘을 이용하기 위해서는 별도의 라이브러리들을 손수 만들어야 하는 문제가 발생한다.

이 때 Matlab에서 제공하는 GUI 툴을 이용하여, 간단하게 GUI를 만들고 동시에 Matlab이 제공하는 막강한 툴박스들을 이용하여 빠르게 작업할 수 있다.

clip_image008

Matlab의 메인 창에서 위의 버튼을 클릭하거나, command 라인에 guide를 입력하면 아래와 같은 다이얼로그 박스가 나타난다.

clip_image011

빈 다이얼로그 박스나, 몇 개의 콘트롤이 기본적으로 포함된 것들 중에서 필요한 것을 선택하면 된다.그러면 아래와 같이 gui의 엘리먼트들을 만들 수 있는 기본 창이 나타난다.

clip_image012

위의 창에서 좌측의 버튼들을 이용하여, 버튼, 라디오 버튼, 체크박스, 에디트 박스, 그래프 콘트롤등의 여러 엘리먼트들을 만들 수 있다.

clip_image014

위의 그림은 이 버튼들을 이용하여 간단한 gui를 만든 상태를 나타낸다. 여기서 기본적으로 해야 할 일은 각 엘리먼트들의 프로퍼티들을 원하는 대로 지정해 주어야 하는 것이다. 각 엘리먼트의 특성에 따라 많은 프로퍼티들이 있지만 가장 기본적인 것은 Tag 프로퍼티이다. Tag프로퍼티는 이 엘리먼트의 ID 를 나타내며, 프로그램 상에서 이 엘리먼트에 접근하여 프로퍼티를 변경하거나, 데이터를 얻어오는 작업등을 수행할 때 필요한 것이다. 그러므로 이 Tag 프로퍼티를 자기가 원하는 이름으로 지정하여 주는 것이 필요하다. 프로퍼티 설정 창은 각 엘리먼트를 더블 클릭하면 볼 수 있다.

clip_image015

이렇게 만들어진 gui를 저장하게 되면 matlab은 기본적인 코드 구조를 자동 생성하여 준다. 코드는 기본적으로 gui생성시 실행되는 opening 함수와, 각 엘리먼트의 콜백 함수로 구성된다. 기본적으로 gui프로그램은 함수들의 집합체이므로, 각 함수에서 공통된 데이터를 다루려면 알고리즘과 관련된 데이터 변수들은 global 변수로 설정하거나, handles 객체에 포함시켜서 다룰 수 있다. 아래에는 gui를 이용한 가장 기본적인 코드를 소개한다.

Edit 박스의 파라미터를 읽어 들여, 버튼을 눌렀을 때, 그래프를 업데이트 하는 프로그램.

 

  1. Opening function

     

    function gui_OpeningFcn(hObject, eventdata, handles, varargin)


    %사용자 변수 정의

    handles.a1=1;

    handles.b1=1;

    handles.a2=1;

    handles.b2=1;

    %타이머 생성

    handles.guifig = gcf;

    handles.t = timer('TimerFcn',{@OnTimer,handles.guifig},'Period', 2.0, 'ExecutionMode','fixedSpacing');

    guidata(handles.guifig,handles);

    start(handles.t);

    %종료시 처리 부분(타이머 종료하기 위해 필요)

    set(hObject,'CloseRequestFcn',@OnClose);

    %GUI 엘리먼트 표시 초기화

    set(handles.edtA1,'String',handles.a1);

    set(handles.edtB1,'String',handles.b1);

    set(handles.edtA2,'String',handles.a2);

    set(handles.edtB2,'String',handles.b2);

    set(handles.edtTime,'String',0);

    %그래프 그리기

    x1=[-10:1:10];

    y1=handles.a1*x1+handles.b1;

    x=[-10:1:10];

    y=[-10:1:10];

    [x2 y2]=meshgrid(x,y);

    z2=handles.a2*x2.^2+handles.b2*y2.^2;

    axes(handles.graph1)

    plot(x1,y1);

    grid on;

    axes(handles.graph2)

    mesh(z2);

    grid on;

    handles.output = hObject;

    guidata(hObject, handles);

    위의 코드에서 붉은 색의 코드가 사용자가 직접 추가한 부분이다.타이머 생성부에서 guifig는 타이머 내부에서 gui의 엘리먼트들을 접근하기 위해 저장하는 figure 핸들이다. 위의 예에서 타이머는 2초 간격으로 설정되어 있다. OnTimer는 이 때 콜백 처리를 위한 사용자 정의 함수이다. Start 명령을 이용하여 타이머를 시작시킨다.

    종료 처리 함수를 작성하지 않을 경우, gui의 종료 이후에도 타이머는 계속 동작하게 된다. 따라서 이를 종료 시키기 위해 사용자 정의 함수가 필요하다.

    GUI에서는 Set 명령을 이용해서 각 element의 프로퍼티를 원하는 값으로 설정할 수 있다. 에디트 박스의 경우, String 프로퍼티가 에디트 박스 안에 나타나는 문자열을 나타내므로, set 명령을 이용하여 원하는 값을 출력하게 만들 수 있다.

    그래프를 그리기 위해서는 axes 명령을 이용하여 원하는 그래프 영역을 선택하고 매트랩의 그래프 관련 명령을 이용하여 그래프를 그릴 수 있다.

  2. 에디트 박스 & 버튼 콜백

    에디트 박스의 콜백은 각 에디트 박스의 값이 변경되었을 때 호출된다. 그러므로 이 함수를 이용하여 입력을 받을 수 있다.

    function edtA1_Callback(hObject, eventdata, handles)


    handles.a1=str2double(get(hObject,'String'))

    guidata(hObject, handles);

    위의 예제 함수와 같이 get 함수를 이용하여 에디트 박스의 string 프로퍼티를 가져오고, 이를 숫자값으로 변경하여 저장한다. 이후 gui 데이터를 업데이트 하는 함수를 반드시 실행 시켜 주어야 한다.

    버튼 콜백 함수를 이용하여 원하는 명령을 실행 할 수 있다.

     

    function btnUpdate_Callback(hObject, eventdata, handles)


    guidata(hObject, handles);

    x1=[-10:1:10];

    y1=handles.a1*x1+handles.b1;

    x=[-10:1:10];

    y=[-10:1:10];

    [x2 y2]=meshgrid(x,y);

    z2=handles.a2*x2.^2+handles.b2*y2.^2;

    axes(handles.graph1)

    plot(x1,y1);

    grid on;

    axes(handles.graph2)

    mesh(z2);

    grid on;

    위의 예제 함수와 같이, guidata 함수를 이용하여, 엘리먼트를 먼저 최종 업데이트 시킨 다음 원하는 작업을 수행하면 된다.

  3. 종료 콜백 함수

    function OnClose(src,evnt)

    h=guidata(gcbo)

    stop(h.t);

    closereq;

    종료 프로시저를 처리하기 위해 위와 같은 코드를 추가한다. guidata(gcbo)를 이용하여 이 이벤트를 호출한 gui의 핸들을 얻을 수 있다. Stop 명령을 이용하여 타이머를 정지 시킨다. Closereq를 이용하여 실제 종료 루틴을 실행 시킨다.

  4. 타이머 콜백 함수

    function OnTimer(obj,event,handles)

    h=guidata(handles);

    curTime=event.Data.time(6);

    set(h.edtTime,'String',curTime);

    guidata(h.guifig,h);

    타이머 이벤트 처리를 위해 위의 코드를 추가한다. 위의 코드는 gui의 에디트 박스에 현재 시간을 출력하는 코드이다.

Timer와 GUI관련 자료는 여기서 찾을 수 있다.

http://groups.google.com/group/comp.soft-sys.matlab/browse_thread/thread/73f1160c0a3724bc/5e259acde22cb9f2?lnk=raot&fwc=1&pli=1

위의 예제 코드는 아래의 링크에서 다운 받을 수 있다.

gui 예제

댓글 없음:

댓글 쓰기