728x90
1. Signal과 Slot이란?
- Signal (신호):
- 객체가 어떤 이벤트가 발생했음을 알리기 위해 발송하는 메시지입니다.
- 주로 클래스 내부에서 정의되며, 특정 조건이 만족될 때
emit
키워드를 사용해 발송됩니다. - Signal은 함수처럼 호출되지만, 직접 실행되지 않고 연결된 Slot을 호출합니다.
- 예시:
signals:
void clicked(); // 버튼이 클릭되었을 때 신호
void valueChanged(int newValue); // 값이 변경되었을 때 신호
- Slot (슬롯):
- Signal과 연결되며, Signal이 발송되었을 때 실행되는 함수입니다.
- 일반 멤버 함수처럼 정의되지만, 특별히
slots:
접근 한정자를 사용하여 정의됩니다. - 예시:
public slots:
void onClicked(); // 클릭 이벤트 처리
void setValue(int newValue); // 값 변경 이벤트 처리
2. Signal-Slot 메커니즘의 작동 원리
- Signal 정의: 클래스에서
signals
접근 한정자를 사용하여 정의합니다. - Slot 정의: 슬롯 함수는
public slots
,private slots
, 또는protected slots
접근 한정자 아래 정의됩니다. - Signal-Slot 연결:
QObject::connect()
함수를 사용하여 Signal과 Slot을 연결합니다.- 연결 시, Signal을 발송하는 객체와 이를 처리할 Slot이 포함된 객체를 지정해야 합니다.
- 예시: 위 코드는 버튼이 클릭되면 애플리케이션이 종료되도록 연결합니다.
QPushButton *button = new QPushButton("Click Me");
QObject::connect(button, &QPushButton::clicked, &app, &QApplication::quit);
- Signal 발송: 특정 조건이 만족되면 Signal을
emit
키워드를 사용해 발송합니다.- 예시:
emit clicked();
- Slot 호출: 연결된 Slot 함수가 호출되어 작업을 수행합니다.
3. Signal-Slot의 특징
- 유연성: Signal과 Slot은 함수의 매개변수만 맞다면 어떤 객체에서도 서로 연결할 수 있습니다.
- 타입 안정성: Signal-Slot은 컴파일 시간에 타입 체크를 수행하여 안전성을 보장합니다.
- 비동기 처리: Signal은 발송된 후, Slot은 이벤트 루프를 통해 호출되므로 기본적으로 비동기적으로 동작합니다.
- 다중 연결: 하나의 Signal은 여러 Slot에 연결할 수 있으며, 하나의 Slot은 여러 Signal에 연결될 수 있습니다.
728x90
4. Signal - Slot 사용조건
- QObject 상속
Signal
과Slot
메커니즘을 사용하려면 클래스가 반드시QObject
를 상속받아야 합니다.- 이는
Signal
과Slot
이 Qt의 메타 객체 시스템 (MOC)에 의해 동작하기 때문입니다. QObject
를 상속하지 않은 클래스에서는Signal
과Slot
을 사용할 수 없습니다.
- Q_OBJECT 매크로
- 클래스 내부에서
Signal
을 정의하거나,Slot
을 사용하려면Q_OBJECT
매크로가 필요합니다. - 이 매크로는 Qt의 MOC에 의해 메타 객체 정보를 생성하도록 지시합니다.
- 예를 들어, Signal 및 Slot을 사용하는 아래 코드에서
Q_OBJECT
가 없다면 컴파일이 실패합니다.
- 클래스 내부에서
class MyClass : public QObject
{
Q_OBJECT // 이 매크로가 없으면 Signal과 Slot이 동작하지 않음
public:
MyClass(QObject *parent = nullptr) : QObject(parent) {}
signals:
void mySignal();
public slots:
void mySlot();
};
5. Signal-Slot의 연결 방식
- Qt 5 이상 스타일 (람다 함수 지원)
connect(sender, &Sender::signal, receiver, &Receiver::slot);
// 람다 함수 연결
connect(button, &QPushButton::clicked, []() {
qDebug() << "Button clicked!";
});
- Qt 4 이하 스타일
connect(sender, SIGNAL(signalName()), receiver, SLOT(slotName()));
두 스타일의 장단점
특성 | Qt 5 이상 스타일 | Qt 4 스타일 |
---|---|---|
타입 안정성 | 컴파일 타임에 타입 체크 가능 | 런타임에만 확인 가능 |
디버깅 용이성 | IDE를 통한 함수 추적 가능 | 문자열 기반으로 추적 어려움 |
호환성 | Qt 4 코드와 혼합 사용 제한적 | 모든 Qt 버전에서 동작 가능 |
람다 지원 | 지원 | 미지원 |
오버로딩된 함수 처리 | 명시적 static_cast 필요(5.7 이상부턴 QOverload ) |
필요없음 |
5. 추가 사항
- Disconnected 연결 해제
- 연결된 Signal-Slot을 해제하려면
QObject::disconnect()
를 사용합니다.
- 연결된 Signal-Slot을 해제하려면
QObject::disconnect(sender, &Sender::signal, receiver, &Receiver::slot);
- Signal 간 연결
- Signal끼리 연결하여 이벤트 체인을 만들 수 있습니다.
connect(sender, &Sender::signal, receiver, &Receiver::anotherSignal);
728x90