5강. 단일 시그널/다중 슬롯

0. 학습 목표
이번 단계에서는 하나의 Signal에 여러 Slot을 연결하는 구조를 학습합니다.
앞에서는 QSlider의 valueChanged(int) Signal을 하나의 Slot 함수와 연결하고,
사용자 정의 Signal을 만들어 값을 다시 전달하는 구조를 살펴보았습니다.
이번 단계에서는 한 단계 더 나아가, 같은 Signal을 여러 Slot 함수에 동시에 연결해 봅니다.
예를 들어 슬라이더 값이 바뀌면 Label도 바뀌고, ProgressBar도 함께 바뀌게 만들 수 있습니다.
또한 사용자 정의 Signal이 발생하면 처리된 값을 Label에도 표시하고, LCDNumber에도 표시할 수 있습니다.
| 학습 목표 | 내용 |
| 단일 Signal / 다중 Slot 이해 | 하나의 Signal에 여러 Slot 함수를 연결할 수 있음을 이해합니다. |
| QSlider valueChanged 활용 | 슬라이더 값 변경 Signal을 Label과 ProgressBar에 동시에 연결합니다. |
| 사용자 정의 Signal 확장 | 처리된 값을 사용자 정의 Signal로 전달하고 여러 Slot에서 사용합니다. |
| QProgressBar 이해 | 슬라이더의 원본 값을 ProgressBar에 반영합니다. |
| QLCDNumber 이해 | 처리된 값을 LCD 형태의 숫자 표시 위젯에 출력합니다. |
이번 단계의 핵심
하나의 Signal은 하나의 Slot만 실행하는 것이 아니라, 여러 Slot을 순서대로 실행할 수 있습니다.
1. Signal / Slot 개념 이해하기
1.1 하나의 Signal에 여러 Slot 연결하기
Qt의 Signal / Slot 구조에서는 하나의 Signal에 여러 Slot을 연결할 수 있습니다.
즉, Signal이 한 번 발생했을 때 여러 함수가 함께 실행될 수 있습니다.
이번 예제에서는 두 종류의 Signal을 사용합니다.
| Signal | 역할 |
| QSlider.valueChanged | 슬라이더 원본 값이 변경될 때 발생하는 기본 Signal입니다. |
| processedValueSignal | 원본 값을 가공한 뒤 처리된 값을 전달하는 사용자 정의 Signal입니다. |
그리고 각 Signal에 여러 Slot을 연결합니다.
QSlider.valueChanged
├── respond_to_slider(value) # 원본 값을 Label에 표시
└── update_progress_bar(value) # 원본 값을 ProgressBar에 반영
processedValueSignal
├── handle_processed_value(value) # 처리된 값을 Label에 표시
└── update_lcd(value) # 처리된 값을 LCDNumber에 표시

이 구조를 사용하면 하나의 이벤트가 발생했을 때 화면의 여러 부분을 동시에 갱신할 수 있습니다.
1.2 기본 Signal에 여러 Slot 연결하기
먼저 QSlider의 valueChanged Signal에 여러 Slot을 연결합니다.
self.slider.valueChanged.connect(self.respond_to_slider)
self.slider.valueChanged.connect(self.update_progress_bar)
위 코드는 슬라이더 값이 바뀔 때 두 개의 Slot 함수가 실행된다는 의미입니다.
| Slot 함수 | 역할 |
| respond_to_slider(value) | 슬라이더 원본 값을 Label에 표시하고, 처리된 값을 사용자 정의 Signal로 emit합니다. |
| update_progress_bar(value) | 슬라이더 원본 값을 ProgressBar에 반영합니다. |
즉, 슬라이더를 움직이면 Label과 ProgressBar가 함께 바뀝니다.
1.3 사용자 정의 Signal에 여러 Slot 연결하기
이번 예제에서는 원본 슬라이더 값을 2배로 처리한 뒤, 사용자 정의 Signal로 다시 전달합니다.
processed_value = value * 2
self.processedValueSignal.emit(processed_value)
그리고 이 사용자 정의 Signal에도 여러 Slot을 연결합니다.
self.processedValueSignal.connect(self.handle_processed_value)
self.processedValueSignal.connect(self.update_lcd)
| Slot 함수 | 역할 |
| handle_processed_value(value) | 처리된 값을 Label에 표시합니다. |
| update_lcd(value) | 처리된 값을 LCDNumber에 표시합니다. |
주의할 점
Qt Designer를 사용할 때 on_processed_value처럼 on_으로 시작하는 함수명은 자동 연결 규칙으로 오해될 수 있습니다.
직접 connect()로 연결할 Slot 함수는 handle_processed_value, update_processed_value처럼 일반 함수명으로 작성하는 것이 안전합니다.
1.4 이번 예제의 전체 흐름
사용자가 슬라이더 이동
↓
valueChanged(int) Signal 발생
↓
respond_to_slider(value) 실행
↓
원본 값 Label 변경
↓
processed_value = value × 2
↓
processedValueSignal.emit(processed_value)
↓
handle_processed_value(value) 실행
↓
처리된 값 Label 변경
동시에
valueChanged(int) Signal
↓
update_progress_bar(value) 실행
↓
ProgressBar 변경
processedValueSignal
↓
update_lcd(value) 실행
↓
LCDNumber 변경
이처럼 하나의 Signal은 여러 Slot을 실행할 수 있고, 각 Slot은 서로 다른 화면 요소를 갱신할 수 있습니다.
2. 예제 코드
2.1 실습 준비
이번 예제는 PyCharm에서 진행합니다.
새 Python 프로젝트를 만들고, 프로젝트 가상환경에 PySide6가 설치되어 있는 상태에서 진행합니다.
예제 파일명은 main.py로 작성합니다.
2. PyCharm 프로젝트 생성
1. 일반 프로젝트 생성하기더보기 2. 커스텀 가상환경으로 프로젝트 시작하기 더보기 PyCharm에서 Custom environment를 선택하는 이유 기본 Project venv를 그대로 사용하지 않고, Virtualenv, Conda, Poetry, uv 같
basiclike.tistory.com
2.2 main.py 예제 코드
import sys
from PySide6.QtCore import Qt, Signal, Slot
from PySide6.QtWidgets import (
QApplication,
QWidget,
QSlider,
QVBoxLayout,
QLabel,
QProgressBar,
QLCDNumber
)
class SliderExample(QWidget):
processedValueSignal = Signal(int)
def __init__(self):
super().__init__()
self.setWindowTitle("단일 Signal / 다중 Slot 예제")
self.resize(300, 220)
self.label_original = QLabel("원본 값: -")
self.label_processed = QLabel("처리된 값(×2): -")
self.slider = QSlider(Qt.Horizontal)
self.slider.setMinimum(1)
self.slider.setMaximum(100)
self.slider.setValue(25)
self.progress_bar = QProgressBar()
self.progress_bar.setRange(0, 100)
self.progress_bar.setValue(25)
self.lcd_number = QLCDNumber()
self.lcd_number.setDigitCount(3)
self.lcd_number.display(50)
self.slider.valueChanged.connect(self.respond_to_slider)
self.slider.valueChanged.connect(self.update_progress_bar)
self.processedValueSignal.connect(self.handle_processed_value)
self.processedValueSignal.connect(self.update_lcd)
layout = QVBoxLayout(self)
layout.addWidget(self.slider)
layout.addWidget(self.label_original)
layout.addWidget(self.progress_bar)
layout.addWidget(self.lcd_number)
layout.addWidget(self.label_processed)
@Slot(int)
def respond_to_slider(self, value):
print("슬라이더 값 변경 :", value)
self.label_original.setText(f"원본 값: {value}")
processed_value = value * 2
self.processedValueSignal.emit(processed_value)
@Slot(int)
def handle_processed_value(self, value):
print("커스텀 시그널 :", value)
self.label_processed.setText(f"처리된 값(×2): {value}")
@Slot(int)
def update_progress_bar(self, value):
self.progress_bar.setValue(value)
@Slot(int)
def update_lcd(self, value):
self.lcd_number.display(value)
if __name__ == "__main__":
app = QApplication(sys.argv)
window = SliderExample()
window.show()
sys.exit(app.exec())
이 코드를 실행하면 슬라이더, 원본 값 Label, ProgressBar, LCDNumber, 처리된 값 Label이 표시됩니다.
슬라이더를 움직이면 원본 값과 ProgressBar가 함께 변경되고, 2배로 처리된 값은 Label과 LCDNumber에 함께 표시됩니다.
슬라이더 값 변경 : 26
커스텀 시그널 : 52
슬라이더 값 변경 : 27
커스텀 시그널 : 54
2.3 예제에서 확인할 핵심 구조
| 코드 | 의미 |
| QProgressBar() | 진행률 형태로 값을 표시하는 위젯입니다. |
| QLCDNumber() | 숫자를 LCD 형태로 표시하는 위젯입니다. |
| valueChanged.connect() | 슬라이더 값 변경 Signal을 여러 Slot에 연결합니다. |
| processedValueSignal.connect() | 사용자 정의 Signal을 여러 Slot에 연결합니다. |
| update_progress_bar() | 슬라이더 원본 값을 ProgressBar에 반영합니다. |
| update_lcd() | 처리된 값을 LCDNumber에 표시합니다. |
2.4 예제 파일
예제 파일은 main.py로 저장합니다.
3. 코드 분석
3.1 주석 포함 전체 코드
import sys # [1] 파이썬 인터프리터 관련 기능을 제공하는 sys 모듈을 가져옴
from PySide6.QtCore import ( # [2] PySide6의 핵심 기능 관련 클래스들 중에서
Qt, # - Qt: 방향, 정렬, 키 값 등 Qt에서 사용하는 공통 상수 제공
Signal, # - Signal: 사용자 정의 Signal을 선언할 때 사용하는 클래스
Slot # - Slot: Slot 함수의 인자 타입을 명확히 표시할 때 사용하는 데코레이터
)
from PySide6.QtWidgets import ( # [3] PySide6의 위젯 관련 클래스들 중에서
QApplication, # - QApplication: 전체 어플리케이션(프로그램)을 관리하는 클래스
QWidget, # - QWidget: 화면에 보이는 기본 창(위젯)의 부모 클래스
QSlider, # - QSlider: 값을 조절할 수 있는 슬라이더 위젯 클래스
QVBoxLayout, # - QVBoxLayout: 위젯들을 세로 방향으로 배치하는 레이아웃 클래스
QLabel, # - QLabel: 화면에 텍스트를 표시하는 위젯 클래스
QProgressBar, # - QProgressBar: 진행률 형태로 값을 표시하는 위젯 클래스
QLCDNumber # - QLCDNumber: 숫자를 LCD 형태로 표시하는 위젯 클래스
)
class SliderExample(QWidget): # [4] QWidget을 상속받아 사용자 정의 창 클래스 생성
processedValueSignal = Signal(int) # [5] 사용자 정의 Signal 선언
# - 정수(int) 값을 전달하는 Signal
# - Signal은 반드시 클래스 변수로 선언해야 함
def __init__(self): # [6] SliderExample 객체가 생성될 때 자동 실행되는 초기화 메서드
super().__init__() # [7] 부모 클래스(QWidget)의 초기화 기능 실행
self.setWindowTitle("단일 Signal / 다중 Slot 예제") # [8] 창 제목 설정
self.resize(300, 220) # [9] 창 크기 설정
self.label_original = QLabel("원본 값: -") # [10] 원본 슬라이더 값을 표시할 Label 생성
self.label_processed = QLabel("처리된 값(×2): -") # [11] 처리된 값을 표시할 Label 생성
self.slider = QSlider(Qt.Horizontal) # [12] 가로 방향 슬라이더 생성
self.slider.setMinimum(1) # [13] 슬라이더의 최소값을 1로 설정
self.slider.setMaximum(100) # [14] 슬라이더의 최대값을 100으로 설정
self.slider.setValue(25) # [15] 슬라이더의 초기값을 25로 설정
self.progress_bar = QProgressBar() # [16] ProgressBar 위젯 생성
self.progress_bar.setRange(0, 100) # [17] ProgressBar의 값 범위를 0~100으로 설정
self.progress_bar.setValue(25) # [18] ProgressBar의 초기값을 25로 설정
self.lcd_number = QLCDNumber() # [19] LCDNumber 위젯 생성
self.lcd_number.setDigitCount(3) # [20] LCD에 표시할 숫자 자리수를 3자리로 설정
self.lcd_number.display(50) # [21] LCDNumber의 초기 표시값을 50으로 설정
# - 슬라이더 초기값 25의 2배 값
self.slider.valueChanged.connect( # [22] QSlider의 valueChanged(int) Signal과
self.respond_to_slider # 첫 번째 Slot 메서드 연결
) # - 원본 값을 Label에 표시하고 처리된 값을 emit함
self.slider.valueChanged.connect( # [23] 같은 valueChanged(int) Signal과
self.update_progress_bar # 두 번째 Slot 메서드 연결
) # - 원본 값을 ProgressBar에 반영함
self.processedValueSignal.connect( # [24] 사용자 정의 Signal과
self.handle_processed_value # 첫 번째 Slot 메서드 연결
) # - 처리된 값을 Label에 표시함
self.processedValueSignal.connect( # [25] 같은 사용자 정의 Signal과
self.update_lcd # 두 번째 Slot 메서드 연결
) # - 처리된 값을 LCDNumber에 표시함
layout = QVBoxLayout(self) # [26] 현재 창에 세로 방향 레이아웃 생성
layout.addWidget(self.slider) # [27] 레이아웃에 슬라이더 추가
layout.addWidget(self.label_original) # [28] 레이아웃에 원본 값 Label 추가
layout.addWidget(self.progress_bar) # [29] 레이아웃에 ProgressBar 추가
layout.addWidget(self.lcd_number) # [30] 레이아웃에 LCDNumber 추가
layout.addWidget(self.label_processed) # [31] 레이아웃에 처리된 값 Label 추가
@Slot(int) # [32] 정수 값을 받는 Slot 함수임을 명시
def respond_to_slider(self, value): # [33] 슬라이더 값이 변경될 때 실행되는 Slot 메서드
print("슬라이더 값 변경 :", value) # [34] 현재 슬라이더 값 출력
self.label_original.setText( # [35] 원본 값 Label 텍스트 변경
f"원본 값: {value}"
)
processed_value = value * 2 # [36] 전달받은 값을 2배로 처리
self.processedValueSignal.emit( # [37] 사용자 정의 Signal 발생
processed_value # - 처리된 값을 Signal로 전달
)
@Slot(int) # [38] 정수 값을 받는 Slot 함수임을 명시
def handle_processed_value(self, value): # [39] 사용자 정의 Signal을 받는 첫 번째 Slot 메서드
print("커스텀 시그널 :", value) # [40] 처리된 값 출력
self.label_processed.setText( # [41] 처리된 값 Label 텍스트 변경
f"처리된 값(×2): {value}"
)
@Slot(int) # [42] 정수 값을 받는 Slot 함수임을 명시
def update_progress_bar(self, value): # [43] valueChanged Signal을 받는 두 번째 Slot 메서드
self.progress_bar.setValue(value) # [44] 슬라이더 원본 값을 ProgressBar에 반영
@Slot(int) # [45] 정수 값을 받는 Slot 함수임을 명시
def update_lcd(self, value): # [46] 사용자 정의 Signal을 받는 두 번째 Slot 메서드
self.lcd_number.display(value) # [47] 처리된 값을 LCDNumber에 표시
if __name__ == "__main__": # [48] 이 파일을 직접 실행할 때만 아래 코드 실행
app = QApplication(sys.argv) # [49] QApplication 객체 생성
window = SliderExample() # [50] 사용자 정의 창 객체 생성
window.show() # [51] 창을 실제로 화면에 표시
sys.exit(app.exec()) # [52] 이벤트 루프(Event Loop) 시작
# - 마우스 클릭, 슬라이더 이동, 창 닫기 등
# GUI 이벤트를 계속 처리함
# - 창을 닫으면 프로그램이 종료됨
3.2 단계별 분석
1단계: 라이브러리 가져오기
from PySide6.QtWidgets import QProgressBar, QLCDNumber
이번 예제에서는 기존 슬라이더 예제에 두 개의 위젯을 추가합니다.
| 위젯 | 역할 |
| QProgressBar | 값을 진행률 막대 형태로 보여줍니다. |
| QLCDNumber | 숫자를 LCD 화면처럼 보여줍니다. |
2단계: ProgressBar와 LCDNumber 생성
self.progress_bar = QProgressBar()
self.progress_bar.setRange(0, 100)
self.progress_bar.setValue(25)
self.lcd_number = QLCDNumber()
self.lcd_number.setDigitCount(3)
self.lcd_number.display(50)

ProgressBar는 슬라이더의 원본 값을 표시합니다.
LCDNumber는 슬라이더 값을 2배로 처리한 값을 표시합니다.
슬라이더 초기값이 25이므로, LCDNumber의 초기 표시값은 25의 2배인 50으로 설정했습니다.
3단계: 기본 Signal에 여러 Slot 연결
self.slider.valueChanged.connect(self.respond_to_slider)
self.slider.valueChanged.connect(self.update_progress_bar)
여기서 하나의 Signal인 valueChanged가 두 개의 Slot에 연결됩니다.
| Slot | 동작 |
| respond_to_slider | 원본 값을 Label에 표시하고, 2배 처리된 값을 emit합니다. |
| update_progress_bar | 원본 값을 ProgressBar에 반영합니다. |
즉, 슬라이더를 한 번 움직이면 두 함수가 함께 실행됩니다.
4단계: 사용자 정의 Signal에 여러 Slot 연결
self.processedValueSignal.connect(self.handle_processed_value)
self.processedValueSignal.connect(self.update_lcd)

사용자 정의 Signal인 processedValueSignal도 두 개의 Slot에 연결됩니다.
| Slot | 동작 |
| handle_processed_value | 처리된 값을 Label에 표시합니다. |
| update_lcd | 처리된 값을 LCDNumber에 표시합니다. |
즉, processedValueSignal.emit(processed_value)가 실행되면 두 함수가 함께 실행됩니다.
5단계: 원본 값을 처리하는 Slot 함수
@Slot(int)
def respond_to_slider(self, value):
print("슬라이더 값 변경 :", value)
self.label_original.setText(f"원본 값: {value}")
processed_value = value * 2
self.processedValueSignal.emit(processed_value)
respond_to_slider()는 슬라이더 원본 값을 받습니다.
받은 값을 Label에 표시한 뒤, 2배로 처리해서 사용자 정의 Signal로 다시 전달합니다.
6단계: 원본 값을 ProgressBar에 반영하는 Slot 함수
@Slot(int)
def update_progress_bar(self, value):
self.progress_bar.setValue(value)

update_progress_bar()는 슬라이더 원본 값을 ProgressBar에 반영합니다.
이 함수는 valueChanged Signal에 직접 연결되어 있으므로, 슬라이더를 움직일 때마다 자동으로 실행됩니다.
7단계: 처리된 값을 Label에 표시하는 Slot 함수
@Slot(int)
def handle_processed_value(self, value):
print("커스텀 시그널 :", value)
self.label_processed.setText(f"처리된 값(×2): {value}")
handle_processed_value()는 사용자 정의 Signal이 전달한 처리 값을 Label에 표시합니다.
예를 들어 슬라이더 값이 25라면, processed_value는 50이 되고 이 값이 Label에 표시됩니다.
8단계: 처리된 값을 LCDNumber에 표시하는 Slot 함수
@Slot(int)
def update_lcd(self, value):
self.lcd_number.display(value)
update_lcd()는 사용자 정의 Signal이 전달한 처리 값을 LCDNumber에 표시합니다.
이 함수도 processedValueSignal에 연결되어 있으므로, emit()이 실행될 때마다 자동으로 실행됩니다.
9단계: 전체 실행 흐름
슬라이더 이동
↓
valueChanged(int) Signal 발생
├── respond_to_slider(value)
│ ├── 원본 값 Label 변경
│ ├── processed_value = value × 2
│ └── processedValueSignal.emit(processed_value)
│ ├── handle_processed_value(processed_value)
│ │ └── 처리된 값 Label 변경
│ └── update_lcd(processed_value)
│ └── LCDNumber 변경
│
└── update_progress_bar(value)
└── ProgressBar 변경

이 구조를 통해 하나의 Signal이 여러 Slot을 실행하고, 그 Slot 안에서 다시 사용자 정의 Signal을 발생시켜 또 다른 여러 Slot을 실행할 수 있음을 확인할 수 있습니다.
4. Qt Designer에서 구현할 때의 구조
4.1 코드 방식과 Designer 방식의 차이
앞의 예제에서는 Python 코드로 슬라이더, Label, ProgressBar, LCDNumber를 직접 만들었습니다.
self.slider = QSlider(Qt.Horizontal)
self.label_original = QLabel("원본 값: -")
self.progress_bar = QProgressBar()
self.lcd_number = QLCDNumber()
self.label_processed = QLabel("처리된 값(×2): -")
Qt Designer를 사용하는 경우에는 위젯을 Designer 화면에서 배치한 뒤, Python 코드에서 해당 위젯에 접근합니다.
self.ui.horizontalSlider
self.ui.labelOriginal
self.ui.progressBar
self.ui.lcdNumber
self.ui.labelProcessed
하지만 Signal을 여러 Slot에 연결하는 구조는 코드 방식과 동일합니다.
4.2 Qt Designer 기반 작업 흐름
Qt for Python 프로젝트 생성
↓
Qt Designer에서 Slider, Label, ProgressBar, LCDNumber 배치
↓
form.ui 파일 저장
↓
form.ui 파일을 ui_form.py로 변환
↓
Widget 클래스에서 사용자 정의 Signal 선언
↓
하나의 Signal에 여러 Slot 연결
↓
화면의 여러 위젯을 동시에 갱신
| 구분 | 코드 방식 | Qt Designer 방식 |
| 슬라이더 | self.slider | self.ui.horizontalSlider |
| 원본 값 Label | self.label_original | self.ui.labelOriginal |
| ProgressBar | self.progress_bar | self.ui.progressBar |
| LCDNumber | self.lcd_number | self.ui.lcdNumber |
| 처리 값 Label | self.label_processed | self.ui.labelProcessed |
4.3 GUI Designer 작업
Qt Designer에서 다음 위젯을 배치합니다.
| 위젯 | objectName 예시 | 역할 |
| Horizontal Slider | horizontalSlider | 값을 조절합니다. |
| Label | labelOriginal | 원본 값을 표시합니다. |
| Progress Bar | progressBar | 원본 값을 진행률로 표시합니다. |
| LCD Number | lcdNumber | 처리된 값을 숫자로 표시합니다. |
| Label | labelProcessed | 처리된 값을 텍스트로 표시합니다. |

4.4 form.ui를 ui_form.py로 변환하기
Qt Designer에서 만든 form.ui 파일은 그대로 Python 코드에서 사용할 수 없습니다.
일반적으로 다음 명령으로 form.ui → ui_form.py 파일로 변환합니다.
pyside6-uic form.ui -o ui_form.py
변환이 끝나면 ui_form.py 파일이 생성됩니다.
이 파일 안에는 Designer에서 배치한 슬라이더, Label, ProgressBar, LCDNumber 정보가 Python 코드로 들어 있습니다.
4.5 ui_form.py 파일 적용하기
Qt Designer 방식에서는 화면 구성을 담당하는 ui_form.py를 가져온 뒤,
Widget 클래스 안에서 기본 Signal과 사용자 정의 Signal을 여러 Slot에 연결합니다.
import sys
from PySide6.QtCore import Signal, Slot
from PySide6.QtWidgets import QApplication, QWidget
from ui_form import Ui_Widget
class Widget(QWidget):
# [1] 사용자 정의 Signal 선언
# - 처리된 정수 값을 전달하기 위해 사용
# - Signal은 반드시 클래스 변수로 선언해야 함
processedValueSignal = Signal(int)
def __init__(self, parent=None):
super().__init__(parent)
self.ui = Ui_Widget()
self.ui.setupUi(self)
# [2] 초기값 설정
self.ui.progressBar.setRange(0, 100)
self.ui.progressBar.setValue(self.ui.horizontalSlider.value())
self.ui.lcdNumber.setDigitCount(3)
self.ui.lcdNumber.display(self.ui.horizontalSlider.value() * 2)
# [3] QSlider의 valueChanged(int) Signal → 여러 Slot 연결
self.ui.horizontalSlider.valueChanged.connect(self.respond_to_slider)
self.ui.horizontalSlider.valueChanged.connect(self.update_progress_bar)
# [4] 사용자 정의 Signal → 여러 Slot 연결
self.processedValueSignal.connect(self.handle_processed_value)
self.processedValueSignal.connect(self.update_lcd)
# [5] 슬라이더 값 변경 Signal을 받는 Slot
@Slot(int)
def respond_to_slider(self, value):
print("슬라이더 값 변경 :", value)
self.ui.labelOriginal.setText(f"원본 값: {value}")
processed_value = value * 2
# [6] 사용자 정의 Signal 발생
self.processedValueSignal.emit(processed_value)
# [7] 사용자 정의 Signal을 받아 처리된 값을 Label에 표시
@Slot(int)
def handle_processed_value(self, value):
print("커스텀 시그널 :", value)
self.ui.labelProcessed.setText(f"처리된 값(×2): {value}")
# [8] 슬라이더 원본 값을 ProgressBar에 반영
@Slot(int)
def update_progress_bar(self, value):
self.ui.progressBar.setValue(value)
# [9] 처리된 값을 LCDNumber에 표시
@Slot(int)
def update_lcd(self, value):
self.ui.lcdNumber.display(value)
if __name__ == "__main__":
app = QApplication(sys.argv)
widget = Widget()
widget.show()
sys.exit(app.exec())

4.6 Designer 방식에서 주의할 점
Qt Designer 방식에서도 하나의 Signal에 여러 Slot을 연결하는 방식은 동일합니다.
self.ui.horizontalSlider.valueChanged.connect(self.respond_to_slider)
self.ui.horizontalSlider.valueChanged.connect(self.update_progress_bar)
위 코드는 같은 valueChanged Signal에 두 개의 Slot을 연결한 것입니다.
중요한 점
Qt Designer 방식에서도 Signal을 여러 Slot에 연결하는 구조는 동일합니다. 다만 Designer에서 만든 위젯은 self.ui를 통해 접근해야 합니다.
| 코드 | 설명 |
| self.ui.horizontalSlider | Designer에서 배치한 슬라이더 위젯에 접근합니다. |
| valueChanged.connect() | 같은 Signal에 여러 Slot을 연결할 수 있습니다. |
| processedValueSignal.connect() | 사용자 정의 Signal도 여러 Slot에 연결할 수 있습니다. |
| handle_processed_value | on_으로 시작하지 않는 일반 Slot 이름을 사용하여 자동 연결 경고를 피합니다. |
5. 정리
이번 단계에서는 하나의 Signal에 여러 Slot을 연결하는 구조를 살펴보았습니다.
핵심 흐름은 다음과 같습니다.
하나의 기본 Signal
↓
self.slider.valueChanged
├── respond_to_slider(value)
└── update_progress_bar(value)
하나의 사용자 정의 Signal
↓
self.processedValueSignal
├── handle_processed_value(value)
└── update_lcd(value)
| 개념 | 정리 |
| 단일 Signal | 하나의 이벤트 발생 신호입니다. |
| 다중 Slot | 하나의 Signal에 여러 Slot 함수를 연결할 수 있습니다. |
| valueChanged | 슬라이더 값이 바뀔 때 발생하는 Signal입니다. |
| processedValueSignal | 처리된 값을 전달하기 위해 만든 사용자 정의 Signal입니다. |
| QProgressBar | 원본 값을 진행률 형태로 표시합니다. |
| QLCDNumber | 처리된 값을 숫자 표시 형태로 보여줍니다. |
이번 단계에서 기억할 문장
Qt에서는 하나의 Signal에 여러 Slot을 연결할 수 있습니다.
이 구조를 사용하면 하나의 사용자 동작으로 화면의 여러 위젯을 동시에 갱신할 수 있습니다.