어쩌라구..?? ㅡㅡa..

Posted
Filed under Linux/programming
오늘도 또 겁나게 삽질했다. 아.. 힘들다..

glade-3를 이용해서 UI를 만들고 libglade를 이용해서 띄우려고 할때
메뉴얼의 Basic 항목대로 프로그램 만들어 놓으면
각 위젯의 realize 이벤트가 발생하지 않는다.
다른 이벤트들은 잘 뜨는데 realize 이벤트만 발생하지 않는다.

realize 이벤트 핸들러에 프로그램 초기화 코드가 들어있는 경우,
당연히 프로그램이 뜨지 않고 죽어버린다. 왜냐고? ㅡㅡ?
이벤트 핸들러 코드가 호출되지 않기 때문이다.

realize 이벤트 핸들러가 호출되지 않는 경우를 살펴보면,
toplevel 위젯의 visible(한글로 '보임') 속성이 yes로 되어있는 경우이다.
properties->common 탭에 보면 있다.

기본으로 glade-3에서 UI를 만들다보면
toplevel 위젯을 만들었을때 기본으로 visible 속성이 no이다.
다른 위젯들은 기본으로 모두 yes가 되어있는데 말이다.
그래서 정작 프로그램을 실행시켰을때
에러메세지가 없는데 아무런 화면이 나오지 않는다.
그래서 다시 glade-3에서 visible속성을 yes로 바꾸고 저장하면 UI가 나온다.

그것이 문제였던 것이다.
메뉴얼의 예제 코드를 보자.
int main(int argc, char *argv[]) {
GladeXML *xml;

gtk_init(&argc, &argv);

/* load the interface */
xml = glade_xml_new("filename.glade", NULL, NULL);

/* connect the signals in the interface */
glade_xml_signal_autoconnect(xml);

/* start the event loop */
gtk_main();

return 0;
}
코드를 보면,
너무도 명백하게 glade_xml_new 함수가 호출되고
glade_xml_signal_autoconnect 함수가 호출된다.

나는 인터넷에서 답을 찾을때까지 저걸 보고서도
왜 이벤트 핸들러가 호출되지 않았는지 몰랐다.
답은 간단하다. UI가 생성된 후에 이벤트 핸들러가 연결되기 때문이다.

glade-3에서 visible 속성이 yes인 위젯들은
glade_xml_new 함수가 리턴될때 이미 모두 디스플레이 되어 있다.
realize 이벤트는 최초 디스플레이될때 발생하는데
벌써 UI가 그려졌으므로 이미 이벤트는 발생했고
그 뒤에 이벤트 핸들러가 등록되므로 당연히 호출되지 않는것이다.
이런 내용을 메뉴얼에서는 찾지 못했다. 나는.

내가 만든 예제 코드를 다시 보자.
int main(int argc, char *argv[]) {
GladeXML *xml;

gtk_init(&argc, &argv);

/* load the interface */
xml = glade_xml_new("filename.glade", NULL, NULL);

/* connect the signals in the interface */
glade_xml_signal_autoconnect(xml);

/* show main window */
gtk_widget_show(glade_xml_get_widget(xml, "window1"));

/* start the event loop */
gtk_main();

return 0;
}
굵게 표시된 부분이 내가 추가한 코드이다.
함수 인자의 "window1"은 glade-3에서 정해준 윈도우 이름으로 바꾸면 된다.
그냥 아무것도 없는 상태에서 윈도우 위젯 만들면 저 이름으로 되길래 넣은것 뿐이다.

코드를 저렇게 수정하고 실행시키면 이벤트가 정상적으로 발생하는것을 볼 수 있다.

아.. 힘들다.
잠좀 자고 싶다.
그래도 할일이 너무나 밀려 있어서 잘 수가 없다. ㅜㅜ
2007/12/17 11:39 2007/12/17 11:39
Posted
Filed under Linux/programming
glade-3로 UI를 만들고 저장하면 소스파일이 전혀 생기지 않고
.glade 파일만 덜렁 생기고 끝이다.
열어보면 XML로 작성된 파일이다.

전에는 glade로 UI 만들고 저장하면 c 소스코드도 줬던걸로 기억하는데
이상하다 생각해서 찾아보니까
glade-3 부터는 아예 소스코드 만드는 기능을 없애버렸다고 한다.
그러면 이걸 어떻게 써먹나... 해서 또 찾아보니까
libglade 라는 라이브러리를 이용해서 프로그램을 띄울 수 있다고 한다.
그래서 써먹어 봤다.

그런데 libglade 홈페이지에서 시킨대로 하니까 이런 에러가 난다.
libglade-WARNING **: could not find signal handler 'some_handler'
이런 제길... ㅜㅜ.

인터넷 조낸 찾아봤는데 질문은 많은데 해결책이 없었다.
쉬벌쉬벌 하면서 찾고, 어찌어찌 하다보니 해결이 됐다.
그래서 나같은 사람 있으면 또 삽질할까봐 글을 남긴다.



libglade  메뉴얼이나 기타 문서를 보면
시그널 핸들러(이벤트 핸들러) 함수가 라이브러리에 있지 않고
바이너리 파일에 있는 경우에는
컴파일 할때 --export-dynamic 옵션을 붙여서 컴파일하라고 한다.
이대로 하면 때려 죽여도 안된다. 적어도 내 리눅스 박스에서는 그랬다.
내가 쓰는 배포판은 우분투 7.10 gutsy 버전인데 안된다.

저 옵션이 아니라 다음 옵션을 써야 한다.
-export-dynamic 또는 -Wl,--export-dynamic
저걸 링커 옵션에 집어 넣어야 한다. 컴파일 옵션에 넣어도 에러 안 나는지는 확인 안해봤다.
Makefile 만들때 LDCONFIG 변수에 때려 박으면 된다.
옵션 글자를 주의 깊게 보기 바란다. 하이픈(-)의 갯수가 다르다.
나 개인적으로는 후자를 추천한다. 옵션이 좀더 명시적이기 때문이다.
그냥 export-dynamic 옵션만 줄때는 하이픈 두개 쓰면 오류나고 하나쓰면 잘 된다.
뭐가 이래... ㅡㅡ;;

스티븐 이거 알아내느라고 하루 꼬박 삽질했다. 바빠 죽겠는데.. ㅜㅜ
부디 이런것 때문에 고생하는 사람 없으면 좋겠다.

추신 : 어떤 메뉴얼에는 하이픈이 한개로 되어있는 메뉴얼도 있었다.
        아마도 gnome쪽 웹 페이지인것 같은데,
        만약 그걸 먼저 봤더라면 이런 고생 안했겠지... ㅜㅜ.
2007/12/16 07:08 2007/12/16 07:08
핑크팬더

감사합니다. 님 덕분에 전 반나절만 고생을 했네요.. ^^

StevenCVAL

헙.. 어쩌다가 이런곳까지 찾아 오셨나요.. ㅡㅡa...
어쨌거나 도움이 되었다니 기쁩니다.

아리새의펜촉

정말 고맙습니다. 하룻동안 붙잡고 고생한 걸 이 글 덕택에 해결하였습니다.

StevenCVAL

어머나.. 어쩌다가 이런곳까지 흘러 오셨는지...
정말 고생 많이 하셨나 봅니다.. ㅡㅡ/