|
[4] QT Programing (4) - SIGNAL과 SLOT |
문의형 []
|
53126 읽음 2002-05-13 04:42 |
|
이번에 알아 볼 부분은
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를 정의 할
때
라는 부분에 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을
정의할 때 사용하는 것입니다.
|
|
이제 앞에서 작성된
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지원에 대해
알아 보도록 하겠습니다.
|
|
관련 글 리스트
|