QT4에서 hello 프로그램을 작성해 보겠습니다. QT4에서는 QT3와는 달리 폼 디자인 뿐이 안됩니다. 제가 설치한 것은 free source 라서 그런 것인지 모르겠습니다만 QT4에서는 프로젝트 메뉴부터 없습니다. 가능한 것은 폼 디자인 뿐이라 프로젝트 파일부터 폼을 위한 헤더와 소스 파일까지 만들어 주어야 합니다.

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

이 시간에는,

  • QT4에서 프로그램을 작성하고 실행하는 방법을 소개하는 것이므로
  • 예제를 매우 간단히 작성하겠습니다.
  • 그리고 같은 프로그램을 임베디드용으로 다시 컴파일해서
  • 임베디드 보드에서 실행해 보겠습니다.

폼디자인

우선 폼 디자인부터 하겠습니다. X11 용으로 파일을 먼저 만들어야 하므로 X11 환경을 세팅합니다.

]$ 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] 버튼을 클릭하시면 프로그램이 종료됩니다.

임베디드 보드에서 실행

이번에는 같은 소스를 가지고, 소스 수정없이 실행 파일을 만들고 임베디드 보드에서 실행해 보겠습니다. 우선 x11을 위한 작업 내용을 없애야 겠습니다.

]$ 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

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

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

프로그램 실행

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

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

잠시 후에 짜잔~ 프로그램이 실행된 것을 보실 수 있습니다.