Kylix Programming Forum
C++Builder  |  Delphi  |  FireMonkey  |  C/C++  |  Free Pascal  |  Firebird
볼랜드포럼 BorlandForum
 경고! 게시물 작성자의 사전 허락없는 메일주소 추출행위 절대 금지
카일릭스 포럼
Q & A
FAQ
팁&트릭
강좌/문서
자료실
컴포넌트/라이브러리
자유게시판
볼랜드포럼 홈
헤드라인 뉴스
IT 뉴스
공지사항
자유게시판
해피 브레이크
공동 프로젝트
구인/구직
회원 장터
건의사항
운영진 게시판
회원 메뉴
북마크
볼랜드포럼 광고 모집

카일릭스 강좌/문서
[4] QT Programing (4) - SIGNAL과 SLOT
문의형 [] 52180 읽음    2002-05-13 04:42
  • SIGNAL과 SLOT(1)

  • 이번에 알아 볼 부분은 QT의 핵심기술이라고 할 수 있는 SIGNAL과 SLOT입니다.
    GUI Programing을 하다보면 어떤 Event, 예를들어 Button을 Click한다거나 혹은 Text Box의 내용을 변경 한다거나 하는것들을 생각해 볼 수도 있고, 또는 어떤 Button을 Click했을때 어떤 특정한 일을 수행하게 한다거나 하는 것도 생각해 볼 수가 있습니다.

    QT에서는 이러한 일들을 SIGNAL과 SLOT이라는 개념으로 처리하는데 이전에 봐 왔었던 예제에서

    connect(quit , SIGNAL(clicked()) , qApp , SLOT(quit()));


    위와 같은 Line이 항상 있었던 것을 기억할 것입니다. 이것이 바로 QT에서의 SIGNAL과 SLOT에 대한 부분인데 connect()라는 Method는 첫번째 인자로 지정한 객체에서 두번째 인자로 지정한 SIGNAL이 발생했을때 세번째 인자로 지정한 객체의 네번째 인자로 지정한 Method를 호출 한다는 뜻입니다.
    즉 quit라는 객체에서 clicked()라는 Event가 발생하면 qApp라는 객체의 quit라는 Method를 호출하는 것입니다.

    QT에서는 QPushButton에 clicked()라든지 qApp에 quit()라는 SIGNAL이나 SLOT들을 미리 정의 하고 있어서 이러한 것들을 사용하거나 혹은 사용자가 직접 SIGNAL이나 SLOT을 만들어 사용할 수 있습니다.
    아래 Code 에서는 직접 SIGNAL을 만드는 방식을 보겠습니다.

    ◎ signslot.h

    1 #ifndef __SIGNSLOT__
    2 #define __SIGNSLOT__
    3
    4 #include <qapplication.h>
    5 #include <qpushbutton.h>
    6 #include <qlabel.h>
    7 #include <qwidget.h>
    8 #include <qmessagebox.h>
    9 #include <qlayout.h>
    10
    11 #define kor(str) QString::fromLocal8Bit(str)
    12
    13 class SignSlot : public QWidget{
    14 Q_OBJECT
    15
    16 public:
    17 SignSlot();
    18
    19 private:
    20 QVBoxLayout *vbox;
    21 QPushButton *quit;
    22 QPushButton *some_act;
    23 QLabel *msg;
    24
    25 public slots:
    26 void Some_Action();
    27 };
    28
    29 #endif //__SIGNSLOT


    ◎ signslot.cpp

    1 #include "signslot.h"
    2
    3 SignSlot::SignSlot(){
    4 setCaption(kor("Signal & Slot"));
    5 setGeometry(200 , 200 , 200 , 200);
    6
    7 vbox = new QVBoxLayout(this);
    8 msg = new QLabel(kor("라벨이라~~~네!") , this);
    9 some_act = new QPushButton(kor("눌러주셔염~") , this);
    10 quit = new QPushButton(kor("종료") , this);
    11
    12 vbox->addWidget(msg);
    13 vbox->addWidget(some_act);
    14 vbox->addWidget(quit);
    15
    16 connect(quit , SIGNAL(clicked()) , qApp , SLOT(quit()));
    17 connect(some_act , SIGNAL(clicked()) , this , SLOT(Some_Action()));
    18 }
    19
    20 void SignSlot::Some_Action(){
    21 QMessageBox::information(0 , kor("SignSlot") , kor("이해가 가나염?") , QMessageBox::Ok);
    22 }
    23
    24 int main(int argc , char *argv[]){
    25 QApplication app(argc , argv);
    26
    27 SignSlot *signslot = new SignSlot();
    28 signslot->show();
    29
    30 return app.exec();
    31 }


    먼저 signslot.h의 14 Line과 26,27 Line이 사용자 정의 SLOT을 만드는 핵심입니다.
    사용자 정의 SLOT을 만들기 위해서는 Class를 정의 할 때

    public slots:


    라는 부분에 SLOT으로 사용할 Method를 지정하고 이를 다음과 같이 연결 시켜 주면 됩니다.

    connect(some_act , SIGNAL(clicked()) , this , SLOT(Some_Action()));



    즉, signslot.cpp의 17 Line은 some_act라는 객체에서 clicked()라는 SIGNAL이 발생하면 this (현재 객체)의
    Some_Action()이라는 Method를 실행 시킨다는 뜻이 됩니다.

    그리고 signslot의 14 Line의 Q_OBJECT라는 KeyWord는 사용자 정의 SIGNAL이나 SLOT을 정의할 때 사용하는 것입니다.

     

  • SIGNAL과 SLOT(2)

  • 이제 앞에서 작성된 Code를 Compile하겠습니다.


    [root@localhost signslot]# progen -o signslot.pro signslot.cpp signslot.h CONFIG+=thread

    [root@localhost signslot]# cat signslot.pro
    TEMPLATE = app
    CONFIG = qt warn_on release thread
    HEADERS = signslot.h
    SOURCES = signslot.cpp
    INTERFACES =
    [root@localhost signslot]# tmake -o Makefile signslot.pro

    [root@localhost signslot]# make
    g++ -c -pipe -Wall -W -O2 -D_REENTRANT -DQT_THREAD_SUPPORT -DNO_DEBUG -I/usr/local/qt-x11-free-3.0.1/include -o signslot.o signslot.cpp
    /usr/local/qt-x11-free-3.0.1/bin/moc signslot.h -o moc_signslot.cpp
    g++ -c -pipe -Wall -W -O2 -D_REENTRANT -DQT_THREAD_SUPPORT -DNO_DEBUG -I/usr/local/qt-x11-free-3.0.1/include -o moc_signslot.o moc_signslot.cpp
    g++ -o signslot signslot.o moc_signslot.o -L/usr/local/qt-x11-free-3.0.1/lib -L/usr/X11R6/lib -lpthread -lqt-mt -lXext -lX11 -lm
    [root@localhost signslot]# ls
    Makefile* moc_signslot.cpp* moc_signslot.o* signslot* signslot.cpp* signslot.h* signslot.o* signslot.pro*
    [root@localhost signslot]#


    먼저 progen을 할때 마지막에 CONFIG+=thread 라고 하면 직접 Project File(.pro)을 열어서 thread라는 항목을 추가하는 것과 같습니다.

    make에서 첫번째는 signslot을 Compile하고 두번째는 moc(/usr/local/qt-x11-free-3.0.1/bin/moc)를 실행시켜서
    moc_sisgnslot.cpp 를 생성합니다. 그 다음 세번째에서는 moc에서 생성된 moc_signslot.cpp를 Compile하고 마지막으로 signalnslot.o , moc_signslot.o를 Compile하여 signalnslot을 만들어 냅니다.

    이 Compile과정에서 우리가 작성한 Header File(signslot.h)을 Compile하는 과정이 없고 단지 moc라는 명령을 사용하여 Header File을 어떻게 하고 있는 과정만 있습니다.

    우리가 작성했던 Header File에는 Q_OBJECT라는 QT에서 사용하는 KeyWord가 있었고 이것은 C++에서 정의 되지 않은
    KeyWord입니다. 즉, 이 Header File을 직접 Compile하려고 하면 Error가 발생할 것입니다.

    여기에서 사용하기위해 QT에서는 moc(Meta Object Compiler)를 제공하고 있고 이를 이용하여 moc_signslot.cpp를 생성한 후 이를 Compile해야 합니다. 그래서 make 과정에서 우리가 작성한 Header File을 직접 Compile하는 대신 moc를 이용하여 moc_signslot.cpp로 만든후 이것을 Compile하는 과정이 들어간 것입니다.

    우리가 작성한 Code의 실행과정은 아주 단순 합니다 '눌러주세요'라는 Button을 Click하면 Some_Action() 이라는 Method가 호출되고 Some_Action() Method는 "이해가 가나염?" 이라는 메시지를 출력해 주는 일을 합니다.


    사용자 정의 SIGNAL이나 SLOT을 만들때는 몇가지 주의 할 점이 있습니다.

    1. SIGNAL과 SLOT을 구현 하는 모든 Class는 QObject에서 상속을 받아야 합니다.
    (여기에서는 QWidget에서 상속을 받았고 QWidget은 QObject에서 상속을 받았으므로 문제가 없습니다.)

    2. CLASS의 선언부의 맨위에 Q_OBJECT라는 KeyWord를 포함해야 하며 이는 moc로 Compile해야 합니다.
    (moc로 Compile하는 작업은 tmake가 Makefile을 만들면서 알아서 작성해 줍니다)

    3. SIGNAL과 SLOT은 Return값이 void여야 합니다.
    4. SIGNAL과 SLOT에 대한 원형은 반드시 Header File에 넣어야 합니다.



    ※ 참고

    signslot.cpp의 21 Line은 QT에서 Message Box를 출력하는 내용인데 이것은 먼저 qmessagebox.h를 Include한 다음
    QMessageBox::information() Method를 호출하면 되는데 첫번째 인자는 Parent로써 다른 Component에 포함 시키지
    않기위해 0을 지정하고 두번째 인자는 Message Box의 Title Bar의 제목 , 세번째 인자는 Message의 내용 , 그 다음 한개 , 또는 그 이상은 Button을 나타 냅니다

    QMessageBox::information(0 , "MSG" , "This is Message" , QMessageBox::Ok , QMessgeBox::Cancle);

    이라고 하면 MSG라는 Title에 This is Message라는 내용을 출력하고 Ok와 Cancle Button이 있는 Message Box가
    출력되고 이의 반환값은 눌려진 Button에 해당하는 정수 값입니다.

    QMessageBox 에는 다음의 Member를 Button으로 지정합니다.

    QMessageBox::NoButton
    QMessageBox::Ok
    QMessageBox::Cancel
    QMessageBox::Yes
    QMessageBox::No
    QMessageBox::Abort
    QMessageBox::Retry
    QMessageBox::Ignore



    다음시간에는 QT에서의 Thread지원에 대해 알아 보도록 하겠습니다.



    + -

    관련 글 리스트
    4 QT Programing (4) - SIGNAL과 SLOT 문의형 52180 2002/05/13
    Google
    Copyright © 1999-2015, borlandforum.com. All right reserved.