개발/PyQt5

PyQt5 - QPushButton 사용법과 Signal/Slot 심화 과정 (3)

TF포지 2025. 4. 21. 23:12

QPushButton프로그램과 사용자의 인터랙션을 연결하는 핵심 도구입니다.

 

이번 포스트에서는 단순히 버튼을 보여주는 데 그치지 않고,

 

버튼 클릭 시 실제 동작을 연결하는 방법 (clicked → connect) 을 실습 위주로 배워보겠습니다.

 

아직 PyQt 설치를 못하신 분들은 아래 글을 참조해주세요.

 

2025.04.19 - [개발/PyQt5] - PyQt5 - PyQt5 개발환경 구성과 Designer 설치 (1)

 

PyQt5 - PyQt5 개발환경 구성과 Designer 설치 (1)

설치부터 GUI 위젯까지이 가이드는 자동매매 구현을 위해 PyQt5를 처음 시작하는 분들을 위해 구성되었습니다.Anaconda 설치 → 가상환경 생성 → Qt Designer 실행까지 기본 개발 환경 설치 방법을 순

tradeforge.tistory.com

 

전체 코드 확인 가능한 깃 주소 : https://github.com/bksj-ds/tfTutorial/tree/master/QtTutorial/QLabel

 

tfTutorial/QtTutorial/QLabel at master · bksj-ds/tfTutorial

Contribute to bksj-ds/tfTutorial development by creating an account on GitHub.

github.com

 


QPushButton의 핵심 – clicked.connect()

clicked.connect()는 PyQt5의 핵심 구조 중 하나로,

 

버튼 클릭(시그널)을 특정 함수(슬롯)에 연결할 수 있도록 도와줍니다.

button.clicked.connect(self.on_button_clicked)

 

이 코드를 통해 버튼을 클릭했을 때, on_button_clicked() 함수가 실행됩니다.


실습 예제 – 버튼 누르면 텍스트 바꾸기

import sys
from PyQt5.QtWidgets import QApplication, QWidget, QPushButton, QLabel, QVBoxLayout

class MyApp(QWidget):
    def __init__(self):
        super().__init__()
        self.initUI()

    def initUI(self):
        self.label = QLabel('아직 클릭 안됨', self)

        self.btn = QPushButton('클릭해보세요', self)
        self.btn.clicked.connect(self.changeText)  # 시그널과 슬롯 연결

        vbox = QVBoxLayout()
        vbox.addWidget(self.label)
        vbox.addWidget(self.btn)

        self.setLayout(vbox)
        self.setWindowTitle('QPushButton 이벤트 예제')
        self.setGeometry(300, 300, 300, 150)
        self.show()

    def changeText(self):
        self.label.setText('버튼이 클릭되었습니다!')

if __name__ == '__main__':
    app = QApplication(sys.argv)
    ex = MyApp()
    sys.exit(app.exec_())

코드 설명

구문 설명
self.btn.clicked.connect(self.changeText) 버튼을 클릭했을 때 실행할 함수를 지정합니다.
changeText() 클릭 시 실행되는 사용자 정의 함수입니다. 이 예제에서는 QLabel의 텍스트를 바꿉니다.
QVBoxLayout() 버튼과 라벨을 수직으로 정렬합니다.

버튼 이벤트 응용 – 여러 버튼 연결하기

여러 개의 버튼이 각각 다른 동작을 하도록 할 수 있습니다.

btn1 = QPushButton('Hello')
btn1.clicked.connect(lambda: self.label.setText('Hello!'))

btn2 = QPushButton('Reset')
btn2.clicked.connect(lambda: self.label.setText('...'))
  • lambda를 활용하면 코드가 훨씬 간단해지고, 복잡한 함수 없이도 빠르게 이벤트를 연결할 수 있습니다.

버튼 클릭 시 다양한 동작 연결하기

동작 코드 예시
파일 열기 btn.clicked.connect(self.open_file)
창 닫기 btn.clicked.connect(self.close)
텍스트 입력창 초기화 btn.clicked.connect(lambda: self.input.clear())

QPushButton과 함께 쓰면 좋은 메서드 정리

메서드 설명
setText() 버튼 텍스트 설정
setEnabled(False) 비활성화 상태로 만들기
setCheckable(True) On/Off 토글 버튼으로 만들기
setIcon(QIcon) 아이콘 추가

QPushButton은 언제 사용하나요?

상황 예시 버튼
적용/닫기 등 기능 버튼 QPushButton
아이콘만 있는 툴버튼 QToolButton
다중 선택이 가능한 경우 QCheckBox
단일 선택 라디오 QRadioButton

어떤 버튼을 써야 할지 고민된다면, “명령을 실행하는 버튼은 QPushButton”입니다.


심화과정 – 커스텀 시그널과 슬롯 만들기

PyQt5에서는 기본 제공 시그널 외에도,

 

개발자가 직접 시그널을 정의하고 필요한 시점에 발생시키는 커스텀 시그널을 만들 수 있습니다.

pyqtSignal로 시그널 선언

QObject을 상속받는 클래스에서 pyqtSignal을 선언하면 됩니다.

from PyQt5.QtCore import pyqtSignal, QObject

class Communicator(QObject):
    custom_clicked = pyqtSignal()

 

이제 custom_clicked라는 시그널을 임의로 발생시켜서 원하는 행동을 연결할 수 있습니다.


실습 예제 – 버튼 클릭 시 커스텀 시그널 발생시키기

import sys
from PyQt5.QtWidgets import QApplication, QWidget, QPushButton, QLabel, QVBoxLayout
from PyQt5.QtCore import pyqtSignal, QObject

# 1. 시그널 정의용 클래스
class Communicator(QObject):
    custom_clicked = pyqtSignal()

class MyApp(QWidget):
    def __init__(self):
        super().__init__()
        self.comm = Communicator()  # 커뮤니케이터 객체 생성
        self.initUI()

    def initUI(self):
        self.label = QLabel('버튼을 클릭해보세요', self)
        self.btn = QPushButton('시그널 발생', self)

        # 2. QPushButton → 커스텀 시그널 연결
        self.btn.clicked.connect(self.emit_custom_signal)

        # 3. 커스텀 시그널 → 슬롯 함수 연결
        self.comm.custom_clicked.connect(self.custom_action)

        vbox = QVBoxLayout()
        vbox.addWidget(self.label)
        vbox.addWidget(self.btn)
        self.setLayout(vbox)

        self.setWindowTitle('Custom Signal Example')
        self.setGeometry(300, 300, 300, 150)
        self.show()

    def emit_custom_signal(self):
        # 버튼을 누르면 커스텀 시그널을 발생시킴
        self.comm.custom_clicked.emit()

    def custom_action(self):
        # 커스텀 시그널을 수신하면 실행됨
        self.label.setText('커스텀 시그널이 발생했습니다!')

if __name__ == '__main__':
    app = QApplication(sys.argv)
    ex = MyApp()
    sys.exit(app.exec_())

작동 흐름 요약

단계 동작
1 커스텀 시그널 custom_clicked 선언
2 QPushButton 클릭 시 emit_custom_signal() 실행
3 이 안에서 custom_clicked.emit() 호출
4 연결된 슬롯 함수 custom_action()이 호출됨

시그널/슬롯을 써야 하는 이유

  • 복잡한 UI 구조에서도 깔끔하게 컴포넌트 간 동작 연결 가능
  • 버튼 → 커스텀 시그널 → 다른 위젯 동작까지 중간 단계 삽입 및 확장이 자유로움
  • 대규모 프로젝트에서도 유지보수성과 확장성이 매우 뛰어남

시그널에 값도 실어보자


custom_clicked = pyqtSignal(str)

self.comm.custom_clicked.emit("헬로우!")

def custom_action(self, msg):
    self.label.setText(msg)
  • pyqtSignal(str) 처럼 데이터 타입 지정 가능
  • emit() 호출 시 데이터를 넘기면, 슬롯 함수에서도 그 값을 받을 수 있음

아무것도 바뀐게 없어보이지만 해당 코드를 사용하여 비동기 적으로 버튼의 동작을 수행 하므로써 QPushButton으로 인한 자동매매 프로그램 동작중 발생할 수 있는 크래시 현상을 완벽하게 방지할 수 있습니다.


이 글이 도움이 되셨다면 공감 ❤️ 과 궁금하셨던 점들을 댓글로 ✍️ 부탁드립니다.

감사합니다.