QT4에서 간단한 hello 프로그램을 작성해서 X11과 Embedded 용 실행 파일로 컴파일해서 각각의 환경에서 실행해 보겠습니다.

잠깐!! 프로그램은 사용자로 로그인해서 작성하겠습니다. 편리를 위해 root 계정에서 모든 작업을 하시는 경우가 많은데, 조금 불편하더라도 사용자 계정을 이용하고 root 계정이 필요할 때에만 su 나 sudo 를 이용하시는 것이 좋습니다. 사용자 계정으로 로그인한 상태에서 캡쳐를 하다보니 셀 프롬프트가 ]$ 입니다. ^^

이 시간에는,

  • QT4 디자이너로 간단한 Hello 프로그램을 작성하고
  • X11 용으로 컴파일한 후 X-Window 에서 실행해 봅니다.
  • 그리고 프로그램 소스 변경 없이 임베디드 실행파일로 컴파일한 후,
  • 임베디드 보드에서 실행해 보겠습니다.

QT 디자이너를 이용해서 QT 프로그래을 만들 든, 아니면 에디터만을 이용하여 프로그램을 작성하든 한 번 만든 소스 파일로 컴파일러만 바꾸어서 X11용 실행파일과 임베디드용 실행파일을 만들 수 있습니다. 그러므로 X Window에서 작업할 수 있도록 환경을 설정( ]$ source .qtx) 한 후, 디자이너로 프로그램을 작성하고 컴파일해서 X Window에서 실행해 본 다음, 다시 타켓 보드를 위한 작업 환경을 설정한 후에 프로그램 소스 변경없이 컴파일한 후, 타겟 보드에서 실행해 보겠습니다.

폼디자인

우선 폼 디자인부터 하겠습니다. 디자이너는 X Window에서 실행되므로 QT환경을 X11로 설정하셔야 합니다. 이 환경 설정을 위해 이전 시간게 .qtx를 만들었습니다. 내용을 다시 보겠습니다.

X11 환경을 위한 .qtx 파일입니다.

]# cd /qt4
]# vi .qtx
#!/bin/bash
export QTDIR=/qt4/qt-x11
export PATH=$QTDIR/bin:$PATH
export LD_LIBRARY_PATH=$QTDIR/lib:$LD_LIBRARY_PATH
export QTINC=$QTDIR/include
export QTLIB=$QTDIR/lib
export qt_prefix=$QTDIR

이번에는 임베디드용 실행 파일을 만들기 위한 환경 설정 파일입니다.

]# cd /qt4
]# vi .qte
#!/bin/bash
export QTDIR=/qt4/qt-arm
export PATH=$QTDIR/bin:$PATH
export LD_LIBRARY_PATH=$QTDIR/lib:$LD_LIBRARY_PATH
export QTINC=$QTDIR/include
export QTLIB=$QTDIR/lib
export qt_prefix=$QTDIR

설치하는 방법과 환경 설정 파일 내용을 보시면 아시겠습니다만 타겟에 따라 QT를 다른 폴더에 설치하고 그 폴더에 맞추어 QT 환경을 설정해 주신 다음 작업을 하시면 되겠습니다.

X11에서 디자이너를 실행하기 위해 .qtx 파일로 환경을 설정합니다.

]$ soruce /qt4/.qtx    // X11로 환경을 설정합니다.
]$ designer &          // 디자이너를 실행합니다.

디자이너를 실행하면 생성할 폼 형태를 선택하는 윈도우가 출력됩니다. "Dialog with Buttons Bottom"을 선택합니다. 그리고 [Create]  버튼을 클릭합시오.

Create 버튼을 클릭하시면 아래와 같이 폼 하나가 생성됩니다. 속성 에디터에서 폼의 이름을 TfrmMain 이라고 입력했습니다.

이 폼에는 벌써 [OK] 와 [Cancel] 버튼의 클릭 시그널에 대한 처리가 되어 있는 상태입니다. Ctrl-R 키를 누르신 후 [OK] 나 [Cancel] 버튼을 클릭해 보세요. 버튼을 클릭할 때 폼이 닫히지요.

생성된 폼에 라벨 위젯을 배치하고 거기에 Hello, Forum Falinux 라고 입력하겠습니다. 폰트도 좀 크게하구요.

예제 프로그램은 여기까지로해서 간단히 하겠습니다. 이제 디자인한 폼을 저장합니다. 저는 폼 이름에 맞추어 frmMain.ui 로 저장했습니다.

필요 파일 생성

한 개의 폼으로 구성되는 프로그램이라도 하더라도 아래의 파일을 만들어 주셔야 합니다.

  • frmMain.h     // frmMain.ui 에 디자인된 폼을 이용하기 위한 헤더 파일
  • frmMain.cpp   // frmMain.ui 에 사용자 코드를 넣는 파일
  • main.cpp      // main() 함수가 들어갈 소스 파일

frmMain.h

frmMain.h 부터 만들겠습니다.

#ifndef  __FRM_MAIN__
#define __FRM_MAIN__

#include "ui_frmMain.h"

class frmMain : public QDialog
{
   Q_OBJECT
private:
   Ui::TfrmMain ui;
public:
    frmMain( QWidget* parent = NULL);
};


#endif

내용을 보니가 알지도 못하는 "ui_frmMain.h" 파일을 include 했습니다. 그리고 frmMain 객체를 선언했고, TfrmMain 의 디자인 정보를 이용하기 위한  ui 변수를 선언했습니다.

ui_frmMain.h는 앞으로 컴파일 과정 중에 생성될 파일이빈다. 지금은 없고 앞으로 만들어질 것을 예상하면서 코드를 한다는 것이 익숙하지는 않습니다만, 이렇게 디자이너로 ui 파일을 만들고 다시 .cpp와  .h 와 같이 소스 파일을 만드는 이 이유는, 물론 제 개인적인 생각입니다만 디자인 파일을 이용하더라도 사용자 코드를 보호하기 위함입니다.

즉, 디자인은 frmMain.ui 에 모두 넣었는데, 여기에 프로그램 코드를 넣을 수 없습니다. 넣는다고 해도 문제입니다. 왜냐하면 나중에 디자이너로 폼을 수정하면 사용자 코드는 사라질 수 도 있기 때문이죠.

혹시, 제가 이전에 올렸던 "QT - QT 2.x.x 디자이너 사용 방법" 글을 보셨나요? 2.x.x 에서도 디자이너로 폼을 생성하고, 그 폼에서 .cpp파일과 .h 파일이 생성되는데, 생성된 .cpp 나 .h 파일에 사용자 코드를 넣으면 컴파일에서 실행파일까지 이상없이 만들어 지지만 폼을 다시 디자이너로 수정한 후에 다시 .cpp 나 .h 파일을 생성하면 어렵게 넣었던 사용자 코드가 사라집니다.

그러므로 폼에서 만들어진 .cpp 나 .h 파일은 손을 대지 말고 대신에 그 폼의 클래스를 상속받아, 상속 받은 파일에 사용자 코드를 넣습니다.

QT4 도 비슷한 방법입니다.. frmMain.ui 에서 TfrmMain의 디자인 정보를 가져와서 그 디자인에 따라 frmMain을 구성하겠다는 것입니다. frmMain.h 내용을 다시 보면 UI::TfrmMain ui; 를 보실 수 있습니다.

class frmMain : public QDialog
{
   Q_OBJECT
private:
   Ui::TfrmMain ui;             // TfrmMain의 UI를 사용할 수 있도록 ui를 선언
public:
    frmMain( QWidget* parent = NULL);
};

frmMain.cpp

frmMain.h 에 frmMain()을 초기화하는 부분이 있습니다. frmMain.cpp 에 내용을 넣습니다.

#include <QMessageBox>
#include "frmMain.h"

frmMain::frmMain(QWidget* parent/*=NULL*/) : QDialog( parent )
{
    ui.setupUi( this);
}

초기화 부분에 ui 를 현재의 폼을 지정해 주고 있습니다. 아직 QT의 세부 구조까지는 자세히 모르겠습니다만, 어째든 사용자는 frmMain.ui 의 디자인 파일을 이용하면서 프로그램에 코드는 frmMain.ui에 입력하는 것이 아니라 frmMain.cpp 나 frmMain.h 에 넣는다는 것이죠.

그래서 결국 디자이너에 의해 ui 파일일 수정되더라도 프로그램 코드는 손상받지 않습니다.

main.cpp

자, 디자인된 폼을 이용할 수 있는 frmMain.cpp와 frmMain.h 파일을 만들었습니다. 이제 C 프로그램 답게 main() 함수가 있어야 겠지요. main()함수가 있는 만큼 파일 이름도 main.cpp 라고 하겠습니다. 그리고 main() 안에 frmMain 객체를 생성하고 화면에 출력하겠습니다.

#include <qapplication.h>
#include "frmMain.h"

int main( int argc, char **argv)
{
  QApplication app( argc, argv);

  frmMain frm;
  frm.show();

  return app.exec();  
}

프로젝트 파일 생성

이제 컴파일을 해서 실행 파일을 만들어 내면 되겠습니다. 그렇게 하기 위해서는 Makefile이 필요한데, Makefile을 만들기 위해서는 프로젝트에 대한 정보 파일이 필요합니다. QT는 다중 플랫폼을 지원하기 때문에 같은 파일을 가지고 서로 다른 프랫폼에서 실행되는 프로그램을 만들 수 있습니다.

그러므로 어떤 파일로 프로젝트를 구성하는지를 얄려 주는 프로젝트 파일인 .pro 를 먼저 만듭니다. 또한 .pro 파일 이름이 실행파일 이름이 되므로 적당한 이름으로 만드러야 겠습니다.

]$ qmake -project -o hello.pro 

qmake 는 -project 옵션을 받으면 그 디렉토리에 있는 모든 파일 정보를 가지고 프로젝트 파일을 생성합니다. -o hello.pro 를 주어 프로젝트 이름을 지정해 주었습니다.

이상없이 작업이 끝나면 hello.pro 파일이 생성됩니다.

이 hello.pro 파일을 만들고 나며 이 파일을 가지고 Makefile을 만들어야 겠습니다. X11용 실행 파일을 만들기 위해서는 qmake 라고만 실행합니다.

]$ qmake

파일 목록을 확인해 보시면 Makefile이 생성된 것을 보실 수 있습니다.

이제 make 를 실행하여 실행파일을 생성합니다.

]$ make 

컴파일이 완료되면 프로젝트 이름과 같은 hello 실행파일이 생성됩니다. 실행합니다.

]$ ./hello 

그러면 화면 중앙에 실행된 프로그램을 보실 수 있습니다.

[OK]나 [Cancel] 버튼을 클릭하시면 프로그램이 종료됩니다.

타켓 보드에 QT 라이브러리 복사

타켓 보드에서 QT 프로그램을 실행시키기 위해서는 리눅스 PC에서와 같이 /qt4/qt-arm/lib 디렉토리에 있는 QT 라이브러리가 필요합니다. 그러므로 다켓보드에도 PC에서처럼 똑 같이 복사해 주어야 하는데 <u>그냥 cp 복사 명령을 이용하면 링크 파일까지 원본으로 복사되어 매우 커집니다.</U> 그러므로 tar로 압축한 후, 타켓 보드에 복사해 넣고 풀기를 합니다.

]$ su
암호:
]# tar zcvf qt4-arm-lib.tar.gz lib
]# mv qt4-arm-lib.tar.gz /home/jwjw/public/

타겟보드에 텔넷으로 연결합니다.

     여기는 타겟 보드에서 작업하는 내용입니다.

falinux login: root
]$ mount -t nfs -o nolock 192.168.10.50:/home/jwjw /mnt/nfs

     lib 파일을 리눅스 PC와 똑 같이 /qt4/qt-arm 에 풀어 놓겠습니다.

]$ cd /
]$ mkdir qt4
]$ cd qt4
]$ mkdir qt-arm
]$ cd qt-arm
]$ tar zxvf /mnt/nfs/public/qt4-arm-lib.tar.gz

임베디드 보드에서 실행

자, 타겟보드에 QT 라이브러리를 설치했으니 프로그램을 실행해 봐야 겠지요. 앞서 만들어진 소수가 X Window에서 실행하던 프로그램이었지만 소스 변경없이 컴파일러만 바꾸어서 타겟보드에서 실행되는 실행파일을 만들어 보겠습니다.

우선 X Window 용 실행 파일을 만들기 위해 만들어진 컴파일과 관려 파일을 모두 삭제하겠습니다.

]$ make clean

테스트에 사용된 임베디드 보드는 ESP-MMI입니다. ESP-MMI는 모니터와 연결할 수 있는 RGB 포트가 있어서 학습하기에 매우 편리한 보드라서 여러 차례 강좌에서 소개한 보드입니다.

Makefile을 새로 생성 및 컴파일

소스 파일은 그래도 사용할 것이므로 프로젝트 파일은 변경하실 필요가 없습니다. 대신에 Makefile을 다켓 보드에 맞추어 새로 생성해야 합니다. 일단 컴파일러부터 크로스 컴파일러를 이용해야 하니까 말이죠.

아래와 같이 qmake 를 이용하여 타켓 보드에 맞춘 Makefile을 생성합니다.

여기서 잠깐!! 아참참참! 이제부터는 qt-x11 이 아닌 qt-arm 을 이용할 것이므로 환경부터 다시 잡아야 겠지요. 환경을 잡고 qmake 를 실행합니다.
]$ source /qt4/.qte
]$ qmake -spec $QTDIR/mkspecs/qws/linux-arm-g++ hello.pro

에러가 없다면 타겟 보드를 위한 Makefile 이 생성되었습니다. make 를 실행하여 타겟 보드용 실행 파일을 만들어 냅니다.

]$ make

프로그램 실행

이제 라이브러리도 복사했으므로 프로그램을 실행할 일만 남았습니다.

]$/mnt/nfs/qt4/01_hello/hello -qws

잠시 후에 짜잔~ 프로그램이 실행된 것을 보실 수 있습니다. 아래의 사진은 ESP-MMI 보드에 LCD를 연결한 후 나무 상자로 담았습니다. 그리고 벽에 걸었습니다. 이렇게 벽에 걸어 놓고 작업하니 키보드와 마우스를 좀더 편리하게 놓을 수 있도록 공간도 넓어지고 보드에 먼지가 쌓이지 않아 여러 모로 좋더군요. ^^