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

List Box !

생각보다 글이 길어져서 GUI의 각 유닛 설명을 몇개의 글로 나눠서 연재하는 중입니다. 지난번에 Push Button, Edit Text, Static Text, Slider Bar를 다루었구요. 이번에는 List Box를 이야기해보겠습니다. List Box를 지난번처럼 빈 팔레트에 한번 가져와보면

위 그림처럼 나타납니다. 간단한 예제를 위해 axes하나와 Push Button도 같이 준비해 두겠습니다. inspector window를 열어보면

String이라는 곳에 표시된 저 아이콘을 누르면

나타나는 창에 위에서처럼 입력해 둡니다. 예 저 내용이 List Box 화면에 나타나는 것이고, 또한, 사용자가 선택하면 반환되는 값이기도 합니다.

m-file 편집없이 그냥 실행하면 나타나는 화면입니다. (바꿔이야기하면 저렇게 꾸미시라는 이야기기도 하지요^^) 이제 call back 함수를 작성할 건데요. listbox나 pushbutton의 tag를 변경하지 않았으니 tag는 분명 listbox1과 pushbutton1으로 되어있을 겁니다. 그 두 tag모두 call back함수가 있을 것이구요. call back함수는 당연히 사용자로부터 입력을 받으면 실행되는 것인데, 저는 그저 pushbutton으로 실행을 시킬거니까 pushbutton1_callback 함수에 내용을 작성할 것입니다. 만약 listbox를 선택하자마자 결과가 나타나게 하고 싶다면, 위 예제에서는 pushbutton을 지우고 제가 지금 부터 설명하는 내용을 listbox1_callback 함수에 위치시키시면 됩니다. 일단, 위 예제는 listbox에 함수를 사용자가 하나 지정하고 PLOT을 누르면 근냥 그림하나 보여 주는 것입니다. Push Button에 들어갈 call back함수의 내용은

입니다. 이걸 부분부분 나눠서 설명하겠습니다.

일단 listbox에서 사용자의 선택이 무엇인지 알아내야겠지요. 방법은 위와같이 하면 됩니다. 먼저 cellstr으로 listbox 전체의 목록을 받아와서 contents에 저장했습니다. 그리고, 그 안에서 어떤 값이 선택받았는지 확인해서 temp1에 저장합니다. 아래 윗 줄에 괄호모양이 다른데요. 이건 cell array인데, 설명한적이(적어도 제 블로그에서는...) 없으니 그냥 저렇게 쓰나보다 하고 넘어가죠.

음... 제가 선정한 함수중에서 나머지는 모두 이름을 그대로 사용하면되는데 cosec와 log는 좀 문제가 있습니다. 일단 cosec는 MATLAB에서는 csc라는 이름을 가지고 있습니다. 그래서 문자열을 비교하는 strcmp라는 함수를 이용해서 조건문을 만들어 두었습니다. 사용자가 cosec를 선택하면 csc라고 생각하라구요. 또한 log(x)는 아시다시피 x에 음의 값이 들어가면 안되니... 정의역을 '0'이상으로 잡도록 해 두었습니다.

이제 이 부분인데요. 물론 if - elseif - end문을 사용해서 일일이 작성해도 되겠지만, listbox에 넣어둔 내용이 어차피 함수이름이라서 eval명령을 사용하기로 했습니다. eval에 대한 설명은 이전에[관련글] 한번 해서 넘어가도록 하겠습니다. 이제 실행하시면

이런 결과를 얻을 수 있습니다.

Pop-up Menu !

ListBox와 Pop-up Menu는 사용법이 동일합니다.

ListBox에서 다루었던 예제에서 ListBox 자리에 Pop-up Menu를 가져다 놓아보죠.

String 속성도 동일하게 잡아주구요.

pushbutton 쪽 callback함수도 동일합니다. 단, handles에서 이름이 popupmenu1로 변경되었을 뿐입니다. 

역시 실행결과입니다.^^.

MATLAB 12. GUI 기초 - ListBox, Pop-up Menu.pdf


댓글을 달아 주세요

  1. 이전 댓글 더보기
  2. 호얌 2011.05.21 22:33 신고

    저도 그대로 따라하는데 윗분처럼 eval에서 오류가 발생하는군요.
    예제가 틀리지 않았나 싶네요~ ㅜ ㅋㅋ

    • BlogIcon PinkWink 2011.05.22 08:15 신고

      글쎼요.. 왜그런지 모르겠네요..
      포스팅하던 당시엔 잘 돌고 있으니까요...
      eval을 사용할때는 ' 의 사용에 조심하셔야합니다. 띄어쓰기 하나도..

  3. 초보초보!!!! 2011.07.15 06:14 신고

    팝업에서 sin에서 log까지 여러 종류를 선택 할 수 있는데, 그 중에 3 개를 순차적으로 클릭해서 리스트 박스(sin, cos, log)에 나타나게 려고 하는데, 팝업에서 한번 클릭하면 리스트 박스에 하나는 나타나는 데 다음에 또 하면 리스트 박스에 있는 정보가 없어지고 새로운 데이터 정보만 리스트 박스에 나타나게 되는데 이걸 어떻게 하면 지워지지 않고 선택하는 순서대로 리스트 박스에 나타나게 할 수 있을 까요......

    • BlogIcon PinkWink 2011.07.15 08:31 신고

      그렇게 구현하고 싶다면, 현재 어떤 것이 선택되었을때, 현재 리스트박스에 저장되어 있는 정보를 읽어오면 됩니다. 그리고 그 저장된 정보와 현재 선택된것을 같이 표현하면 될것 같습니다.

    • 초보초보!!!! 2011.07.16 01:54 신고

      감사합니다. 쓰신 내용 곰곰히 생각해서, 현재 값 저장한 다음에 다음 값 다시 저장하는 걸 만들어서 하니까 어찌어찌 되네요. 감사^^

      질문1 이렇게 저장된 리스트 박스에 delete 버튼을 만들어서 선택된 파일을 리스트 박스에서 하나씩 지우는 기능과,
      질문2 버튼을 하나 더 만들어서 한꺼번에 다 지우는 기능을 생각 중인데, 이거두 조언 부탁드립니다!!!

      delete버튼 콜백으로
      handles.selected_strings=[]; % 리스트박스 스트링 저장
      delete(get(handles.listboxSelectedLines));
      guidata(hObject, handles);

      이렇게 하면 리스트 박스에 표시된 내용은 지워지고, 저장된 데이터도 지워질 줄 알았는데, 실제로 버튼을 누르면 저장된 내용은 지워지는데 표시된(displayed) 내용이 안 없어집니다. 그리고 get를 빼니가 박스가 통채로 없어 지내요...쩝....

      한개씩 지우는 건 더 어려운 것 같아서 통채로 지우는 것 부터 하려고 그럽니다. 한수 부탁드립니다.^^

    • BlogIcon PinkWink 2011.07.16 14:05 신고

      set으로 공백문자를 입력하는 것되 괜찮지 않을까요...
      그리고 말씀하신 부분은 일종의 히스토리기능으로
      이전것을 저장하는 것이 가능해졋다고 하셨으니
      그걸 행렬로 저장하는 개념을 확립하시면 됩니다.
      그러면 히스토리 기능을 구현하실 수 있을겁니다.

  4. 초보초보!!!! 2011.08.05 07:20 신고

    오랫만에 또 질문이 있어서 왔습니다. ^^
    일단 설명을 드리면 두개의 푸시버튼을 만듭니다. (start, stop)
    start 버튼을 누르면 5분마다 'test pause function'이 찍히도록 하고
    stop 버튼을 누르면 위 동작이 중단되는 걸 만들려고 하는데,
    문제는 일단 시작을 하면 동작은 잘 되는데 멈추지를 않습니다.
    알고리즘은
    RT_index ==1이면 동작이 진행되도록 만들었기 때문에
    stop버튼 콜백에 RT_index == 0을 넣어서 값이 변하도록 만들었는데
    왜 값이 안 바뀌는지 모르겠습니다. 구이 오프닝에서 RT_index =1로 설정을 하긴 했는데 이 값은 처음이 구이 시작될 때 입력되는 값이고, stop 콜백으로 업데이트를 하면 값이 바뀌어야 할 것 같은데 잘 안되네요.

    function Guitest_OpeningFcn(hObject, eventdata, handles, varargin)
    handles.RT_index =1;
    guidata(hObject, handles)

    function pushbuttonStart_Callback(hObject, eventdata, handles)
    RT_index = handles.RT_index;
    while (RT_index == 1)
    pause on
    pause(300)
    disp('test pause function')
    pause off
    RT_index = handles.RT_index;
    end

    function pushbuttonStop_Callback(hObject, eventdata, handles)
    handles.RT_index = 0;
    disp('stop button')
    guidata(hObject, handles)

    • BlogIcon PinkWink 2011.08.05 12:48 신고

      함수내부 변수는 지역변수입니다.
      다른 함수에서도 사용하실려면 출력으로 잡으시던지 혹은
      글로벌로 선언해서...
      다른 함수에서 변경해도 그 변경값이 적용되도록 하셔야합니다.

  5. 초보초보!!!! 2011.08.09 07:22 신고

    조언 감사드립니다. ^^
    질문이 하나 더 있습니다.
    5분마다 데이터를 받는 루프를 만들려고 while를 썼는데 while문 밖에서 while을 실행 중지 시킬 수 있는 건가요? 찾아보니까 보통 while문 안에 어떤 조건에 걸리면 break로 중지 시키던데 이것 말고 계속 실행하다가 외부에서 어떤 명령어를 넣으면 강제 종료 시키는 그런 기능을 찾고 있는데 못 찾겠네요.
    예를들면 커맨드 윈도우 상에서 ct + c 이런 기능을 하는 강제 종료 기능을 찾고 있습니다.

    매번 감사드립니다!!

  6. 초보초보!!!! 2011.08.09 13:56 신고

    ㅠ.ㅠ
    모르시는 군요. 다른 기능이 실행 될 경우 while 루프 종료 시킨 후에 기능을 실행하고, 그 기능이 끝나면 다시 while루프 돌릴라구 그랬는데...쉽지 않겠네요....쩝..
    어쨌든 감사합니다.

    • BlogIcon PinkWink 2011.08.09 19:38 신고

      안타까운일이죠...
      그러나 다시 생각하면, 외부에서 while문을 종료시킬 상황이라는 것 자체가 이해되지 않는 부분입니다.
      다시 말씀드리지만, while문을 종료시켜야하는 상황이 생겼다는 것은 while문이 돌고 있다는 의미이고, 결국 while문 내부에서 종료시키는 것 아닌가요?

  7. 초보초보!!!! 2011.08.09 23:44 신고

    예 맞는 말입니다. 그런데 while이 돌고 있는 중에 외부에서 어떤 이벤트가 생기면 while 루프를 종료시키면 되는 거죠. 그런데 이런 외부에서 생긴 이벤트를 while 내부에서 알수 있다면 문제가 되지 않을 것 같습니다. 이것에 대한 아이디어가 혹시 있으신가요?

    • BlogIcon PinkWink 2011.08.10 08:46 신고

      MATLAB에서 특정 엑션이 취해졌을때, 그 상황을 저장하는 변수(?)가 있습니다. (지금은 그게.. 기억이 . ㅠㅠ 아놈의 기억력같으니라고..ㅠㅠ) 그 변수의 내용을 체크하시다가, 반복문을 종료하는 건 어떨지요. 그러나... 정확한 조언은 아닙니다. 하도 오래전이고, 사람마다 프로그램을 작성하는 습관이 달라, 저는 그와 같은 상황을 만난적이 없어서요.

  8. 초보초보!!!! 2011.08.11 08:51 신고

    계속 찾고 있는데 좀 어렵네요. 매번 ctrl+c를 쓸 수도 없고...아..... 조언 감사합니다.

  9. Matlab초보 2011.09.10 17:21 신고

    의공학을 공부하는 대학교2학년 학생입니다. 매트랩공부 중 우연히 블로그를 발견해서 참 많은 도움이 되고잇었는데욤.. ㅎㅎ 제가 지금 gui로 사진불러오기를 하고잇습니다. 그리고 그 listbox에 그 각 이미지의 이름을 정렬시켰는데 각 이름을 누를때 마다 그 이름에 해당하는 사진을 띄울려고 합니다. 그래서 위에서 하신것 처럼 받아서 출력은 되는데 다른 이름을 눌렀을 떄 다른 사진으로 이동이 안됩니다 ㅠㅠ 소스는

    contents=cellstr(get(handles.listbox1, 'String'));
    temp=contents{get(handles.listbox1, 'Value')};

    for j=1:size(FN,2)
    if strcmp(temp, FN(1,j))
    hImg=imshow(I(:,:,j), 'Parent', handles.axes1, 'DisplayRange', []);
    end
    end

    요렇게 되어있습니다... 마지막 end후에 다시 처음으로 돌아가지 못하는 것이라고 생각하고 while 문을 돌렷는데... 아예 랙이 걸려서 안돌아 가더군요 ㅠㅠ 참 FN에 사진이름이 저장되어있습니다. 계속 다른 이름을 클릭했을 떄 다시 돌아가게 하는 방법이 무엇인지 질문 드립니다.ㅠㅠ

    • BlogIcon PinkWink 2011.09.12 15:53 신고

      음... 저도 잘 모르겠습니다. 다른 설정과 여타 코드가 정상이라는 가정하에...
      for문의 end 다음에.. 단순히 글자를 출력하는 것을 한 줄 넣으셔서.. for문이 정상적으로 종료했는지를 확인해보실 필요가 있다는 생각도 듭니다.

  10. f 2011.12.03 18:08 신고

    Warning: single-selection listbox control requires that Value be an integer within String range
    Control will not be rendered until all of its parameter values are valid.

    명령창에서 이렇게 뜨면 뭘 고쳐야하는걸까요.....?ㅠㅠ

  11. 2011.12.21 03:51 신고

    안되잔아요 아 이거 떄문에 여섯시간 고민했음

    • BlogIcon PinkWink 2011.12.21 13:00 신고

      어디가.. 원인은.. 어떻게 했길래.. 뭐 이런게 있어야하지 않을까요.
      그리고, 이 글만 6시간 고민할 건 없는데 말이죠.
      MATLAB을 처음하는 40대 직장인을 대상으로한
      당시 저의 강의 자료이고
      당시 실습생 40여명이 다들 따라서 진행했었습니다만...
      6시간이라....ㅠㅠ

  12. 안되요 2012.01.18 15:49 신고

    저도 eval 에서 에러가 나는데요....

    eval(['plot(handles.axes1, t, 'temp1'(t))'])

    에서 보니까 'plot(handles.axes1, t, '까지를 하나로 인식하네요....?

    • BlogIcon PinkWink 2012.01.18 16:03 신고

      eval(['plot(handles.axes1, t, 'temp1'(t))'])

      이렇게 하시면 안되고

      eval(['plot(handles.axes1, t, ' temp1 '(t))'])

      이렇게 하셔야합니다. eval내에서 '를 사용할 경우 빈 칸 하나가 '의 안쪽에 열리고 닫히는 곳에 하나씩 들어가 주어야 합니다.

  13. 안되요 2012.01.18 17:50 신고

    음....되는군요...감사합니다.

    저기...한 가지 더 여쭈어봐도 될까요?

    이미지를 불러서 디스플레이하고 싶은데...imshow라는 명령어로요.

    axes에다 하니까 안돼드라구요...

    어디에 해야 할까요?

    답변 주실 줄로 알고 미리 감사드립니다.

    • BlogIcon PinkWink 2012.01.19 09:26 신고

      저도 안해봤습니다.ㅠㅠ
      그러나 imread로 그림화일을 읽어보면, 그 결과가 배열형태의 변수로 저장된다는 것을 알 수 있습니다.
      결국, RGB값을 직접 뿌리면 아마 일반 figure에 저장될 것으로 보입니다.

  14. Hoi_Hoi 2012.03.30 05:58 신고

    정말 좋은 강좌 이네요. 덕분에 프로그램 잘짜고 있습니다. 감사 합니다. 여러 매뉴얼을 읽어 봤지만 제일 클리어 하는것 같습니다. ㅎ

  15. 항일오구어 2013.04.27 13:49 신고

    실행은 되는데 plot누르면 이런 문구가 뜨네요 ==>Error while evaluating uicontrol Callback

    • BlogIcon PinkWink 2013.04.30 19:52 신고

      아 그래요? 당시엔 아무 문제가 없었는데, 지금은 소스를 다시 실행할려면 그림부터 그리고 해야해서... 말씀하신 에러를 잡기는 좀 힘든것도 있어요.

  16. Work 2013.11.19 01:09 신고

    리스트박스안에 pushbutton을 눌러서 데이터를 넣으려면 어떻게 해야하나요?
    코드를 도저히 못짜겟어서 질문드려요

    • BlogIcon PinkWink 2013.11.19 09:13 신고

      리스트박스안에 푸쉬버튼을 넣는다구요???
      글쎄요. 전 잘 모르겠는데요.
      왜 그래야하죠?
      리스트박스안의 항목은 클릭하면 되는데 왜 또 푸쉬버튼을 넣을려고 하나요???

  17. kkz1228 2015.07.18 16:36 신고

    저 혹시 cellstr을 이용해서 만든 행렬의 특정 원소를 따로 지정하고싶은데요(다른 변수와의 연산에서 행렬 차수를 맞추기위해서) 혹시 어떤 식으로 소스를 작성하면 될까요?ㅠㅠ

  18. dodo 2015.12.03 23:01 신고

    저는 첫번째 푸쉬버튼 함수에서 set으로 list box에 들어갈 내용을 넣어준뒤
    다른 푸쉬버튼 함수에서 set으로 list box에 들어갈 내용을 추가해줬습니다.
    근데 두번째 푸쉬버튼을 눌렀을 때 목록상자가 아예 없어지더라구요.....
    경고: Single-selection 'listbox' 컨트롤에서 'Value' 는
    문자열 범위 내의 정수여야 합니다.
    파라미터 값이 모두 유효한 값이 되어야만 컨트롤이 렌더링됩니다.
    이런 오류가 뜨면서요.....
    그 gui하나 만들면 각각의 함수가 생기는데 끝에 end 안쳐줘서 그런가요?? ㅠ,ㅠ

    • BlogIcon PinkWink 2015.12.04 10:13 신고

      흠.. 잘 모르겠습니다. 사실. 이 본문을 작성한 이후 직장생활을 시작하면서 GUI를 제가 손댈일이 없어서요~~^^ 도움이 되지 못했네요.ㅠㅠ

  19. 감사 2015.12.05 14:09 신고

    각 listbox의 함수의 축이 모두 다른데 어떻게 설정해야 될지 모르겠어요ㅜㅜ
    그리고 listbox 에서 함수를 하나 보여준 후에
    밑에다가 data를 입력할 수 잇는 창을 하나 넣은 후에
    사용자가data 를 입력하면 그 값이 plot 위에 표시가 되게 할수는 없나요?

    • BlogIcon PinkWink 2015.12.06 09:58 신고

      가능할겁니다. 마우스가 단지 올라가 있는지 클릭한건지 부군지을 수 있으니까요... 그런데.. 지금 제가 그걸 해볼 수는 없네요.. 바로 위 댓글에 답했지만.. 이제 사회생활을 시작한지 너무 오래되어서 다시 익힐려면 시간이 좀 필요할텐데 제가 그 여유가 없어서요^^

  20. boooong 2017.06.11 02:36 신고

    list box 작성하다가 안돼서 질문드려요ㅠㅠ 혹시 FDATOOL을 이용해서 필터를 만들어서
    [ss,FFFs ]= audioread('RICH.wav');
    yft=filter(Num, 1, ss);
    로 wav파일 필터링 해서 fft 그래프 나타냈는데
    gui 에서 listbox에 포함시켜서 하려니까 실행이 안되네요..ㅠㅠ FDATOOL는 listbox로 연계되지가 않는지 질문드립니다...!

    • BlogIcon PinkWink 2017.06.12 07:33 신고

      저는 현재 MATLAB을 사용할 수 없어서 답변을 드릴수가 없지만,,
      연계?되지않는지 모르지만 될겁니다.. 단지 어떻게 접근했는가의 문제가 아닐까요...

  21. 진짜 초보 2018.06.02 22:25 신고

    eval(['plot(handles.axes1,t,'temp1'(t))'])
    이렇게 사용했는데 temp 구문에 오류가 발생했다고 나오네요 ㅠㅠ
    왜그런가요??

    • BlogIcon PinkWink 2018.06.04 02:04 신고

      정확하게 잘 모르겠습니다.
      이 글이 작성될 때와 지금은 버전이 달라서 명령의 각 옵션들이 조금씩 바뀌었는지
      혹은 해당 코드와 그 앞 코드의 문제인지 말이죠ㅠㅠ.