예제
시그널이 발생하면 윈도우 상에 배치된 라벨의 텍스트를 출력하는 예제를 만들어 보자.
widget.h의 SignalSlot 클래스
...
class SignalSlot: public QObject{
Q_OBJECT
public:
void setValue(int val){
emit valueChanged(val);
}
signals:
void valueChanged(int newValue);
private:
int value;
};
...
Signal 함수
signals:
void valueChanged(int newValue);
- 시그널 함수는 구현부가 없으며, 헤더에 정의부만 구현한다.
- 위의 예제에서는 시그널 함수에 int 인자를 명시했지만, 이 인자는 시그널 발생 시 값을 슬롯 함수에게 인자로 전달하는 역할(필요에 따라 인자를 사용하지 않거나 여러개 사용할 수도 있다.)
멤버 함수
public:
void setValue(int val){
emit valueChanged(val);
}
- 이 멤버 함수가 호출되면, 함수 내 emit이 시그널을 발생시킨다.
widget.h의 Widget클래스
...
class Widget : public QWidget
{
Q_OBJECT
public:
Widget(QWidget *parent = nullptr);
~Widget();
private:
QLabel *label;
public slots:
void setValue(int val);
};
...
Slots
public slots:
void setValue(int val);
- slots의 접근제한자는 private 또는 public과 함께 사용이 가능하다.
- slots라는 키워드를 사용하여 명시한 멤버 함수는 Slot 함수를 정의가 가능하다.
widget.cpp
#include "widget.h"
Widget::Widget(QWidget *parent)
: QWidget(parent)
{
label = new QLabel("",this);
label->setGeometry(10,10,250,40);
SignalSlot myObject;
// new style
connect(&myObject, &SignalSlot::valueChanged, this, &Widget::setValue);
// old style
//connect(&myObject, SIGNAL(valueChanged(int)), this, SLOT(setValue(int)));
myObject.setValue(50);
}
void Widget::setValue(int val){
QString labelText = QString("Signal emmit, Value : %1").arg(val);
label->setText(labelText);
}
Widget::~Widget()
{
}
connect() 함수
// new style
connect(&myObject, &SignalSlot::valueChanged, this, &Widget::setValue);
// old style
connect(&myObject, SIGNAL(valueChanged(int)), this, SLOT(setValue(int)));
- 첫 번째 인자: 이벤트가 발생한 오브젝트(클래스 인스턴스)
- 두 번째 인자: 오브젝트의 시그널(이벤트)
- 세 번째 인자: 시그널과 호출할 슬롯 함수가 있는 오브젝트 이름
- 네 번째 인자: 시그널 발생 시, 호출 할 슬롯 이름
new style
- Qt 5.5 이상 버전에서 추가된 방식
- 여러 개의 인자 사용 불가능
- Slot 함수 뿐만 아니라 일반 멤버 함수도 Slot 함수와 같이 connect() 함수에서 4번째 인자로 사용 가능
흐름
1. cpp 코드에서 Signal 선언된 클래스 선언
SignalSlot myObject;
2. Signal과 Slot을 connect
connect(&myObject, &SignalSlot::valueChanged, this, &Widget::setValue);
2. myObject 객체의 멤버 함수 호출
myObject.setValue(50);
3. 멤버 함수의 emit이 시그널 발생
public:
void setValue(int val){
emit valueChanged(val);
}
4. 시그널이 발생하면 연결된 슬롯이 실행
public slots:
void setValue(int val);
...
void Widget::setValue(int val){
QString labelText = QString("Signal emmit, Value : %1").arg(val);
label->setText(labelText);
}
5. 결과
6. 흐름도
요약
- emit이 호출되면 시그널을 발생시킨다.
- 시그널은 함수 구현부가 없으며, 헤더에만 정의 구현만 한다.
- 예제와 같이 Signal고 Slot 함수는 다른 클래스에만 구현되어 있어야 되는 것은 아니다.
- 동일한 클래스에 존재하는 Signal이 Slot 함수를 호출 할 수 있다.
- Signal이 Signal을 호출 할 수 있다.
- Signal과 Slot을 사용하려면 class 내부에 무조건 Q_OBJECT를 선언해야된다.
'🌠Development > QT' 카테고리의 다른 글
QT - Dialog (0) | 2024.07.12 |
---|---|
QT - Signal and Slot (3) (0) | 2024.07.12 |
QT - Signal and Slot (1) (0) | 2024.07.11 |
QT - Layout (1) | 2024.07.11 |
QT - 계산기 만들기 (0) | 2024.07.11 |