Profile picture

[Python] PySide6를 활용하여 GUI 개발해보기

JaehyoJJAng2024년 08월 14일

개요

PySide6는 파이썬에서 Qt 라이브러리를 사용할 수 있도록 도와주는 도구로, 다양한 플랫폼에서 GUI 애플리케이션 개발이 가능하다.

이번 글에서는 PySide6를 이용해 기본적인 GUI 프로그램을 만드는 법부터 멀티스레딩을 구현하는 방법까지 단계별로 기록해보려고 한다.

예제 코드를 작성하여 GUI 프로그램을 개발해보고, QThread를 활용해 긴 작업을 백그라운드에서 실행하는 법까지 실습해보자!


PySide6란 무엇인가?

PySide6는 Qt 라이브러리의 Python 바인딩으로, 크로스 플랫폼 애플리케이션을 개발할 수 있는 프레임워크입니다.

PySide6를 사용하면 Python 코드로 윈도우, 버튼, 레이블 등의 GUI 요소를 손쉽게 구현할 수 있습니다.

또한, Qt의 강력한 기능을 활용하여 복잡한 애플리케이션도 빠르게 개발할 수 있습니다.


기본적인 PySide6 GUI 프로그램 만들기

먼저, 아주 간단한 GUI 프로그램을 만들어보자.

이 프로그램은 Hello, World! 라는 메시지를 표시하는 윈도우를 생성한다.

import sys
from PySide6.QtWidgets import QApplication, QLabel, QMainWindow

# 메인 애플리케이션 실행 코드
app = QApplication(sys.argv)  # QApplication 객체 생성
window = QMainWindow()  # QMainWindow 객체 생성
window.setWindowTitle("Hello, World!")  # 윈도우 제목 설정
window.setGeometry(300, 300, 400, 200)  # 윈도우 위치와 크기 설정

label = QLabel("Hello, World!", parent=window)  # 레이블 생성 및 윈도우에 추가
label.setGeometry(100, 80, 200, 40)  # 레이블 위치와 크기 설정

window.show()  # 윈도우 표시
sys.exit(app.exec())  # 애플리케이션 이벤트 루프 실행

코드 설명

  • QApplication은 애플리케이션을 관리하는 클래스이다.
  • QMainWindow는 기본적인 윈도우 기능을 제공하며, 여기에 위젯도 추가할 수 있다.
  • QLabel은 텍스트를 화면에 표시하는 위젯이다.

객체지향적으로 GUI 프로그램 개발하기

이제 코드를 객체지향적으로 작성하여 GUI 프로그램의 구조를 명확하게 하고, 코드의 재사용성과 유지보수성을 향상시켜보자.

import sys
from PySide6.QtWidgets import QApplication, QLabel, QMainWindow, QPushButton, QVBoxLayout, QWidget

# 메인 윈도우 클래스 정의
class MainWindow(QMainWindow):
    def __init__(self):
        super().__init__()  # 부모 클래스의 생성자 호출
        self.setWindowTitle("Object-Oriented Example")  # 창 제목 설정
        self.setGeometry(300, 300, 400, 200)  # 창 위치와 크기 설정

        # 중앙 위젯과 레이아웃 설정
        self.central_widget = QWidget()
        self.setCentralWidget(self.central_widget)

        self.layout = QVBoxLayout()
        self.central_widget.setLayout(self.layout)

        # 레이블과 버튼 추가
        self.label = QLabel("Hello, Object-Oriented World!")
        self.layout.addWidget(self.label)

        self.button = QPushButton("Click Me!")
        self.layout.addWidget(self.button)

        # 버튼 클릭 시 이벤트 처리 메서드 연결
        self.button.clicked.connect(self.on_button_click)

    # 버튼 클릭 시 실행되는 메서드
    def on_button_click(self):
        self.label.setText("Button Clicked!")

# 메인 애플리케이션 실행 코드
if __name__ == "__main__":
    app = QApplication(sys.argv)
    window = MainWindow()
    window.show()
    sys.exit(app.exec())

QThread로 멀티스레딩 구현하기

GUI 애플리케이션에서 시간이 오래 걸리는 작업은 메인 스레드에서 실행하게 되면 프로그램이 응답하지 않는 현상이 발생하게 된다.

이를 방지하기 위해 QThread를 사용해 작업을 백그라운드에서 실행하도록 해보자!


아래 예제는 버튼 클릭 시 5초 동안 작업을 백그라운드에서 진행하며, 작업의 진행 상황을 업데이트 한다.

import sys
import time
from PySide6.QtCore import QThread, Signal
from PySide6.QtWidgets import QApplication, QLabel, QMainWindow, QPushButton, QVBoxLayout, QWidget

# 백그라운드 작업을 처리할 QThread 클래스 정의
class WorkerThread(QThread):
    # 작업 상태를 업데이트하기 위한 사용자 정의 시그널
    progress = Signal(int)

    def run(self):
        # 긴 작업 시뮬레이션 (5번 반복하며 1초 대기)
        for i in range(1, 6):
            time.sleep(1)  # 1초 대기
            self.progress.emit(i)  # 진행 상황 시그널 발행

# 메인 윈도우 클래스 정의
class MainWindow(QMainWindow):
    def __init__(self):
        super().__init__()
        self.setWindowTitle("QThread Example")
        self.setGeometry(300, 300, 400, 200)

        self.central_widget = QWidget()
        self.setCentralWidget(self.central_widget)

        self.layout = QVBoxLayout()
        self.central_widget.setLayout(self.layout)

        self.label = QLabel("Click the button to start.")
        self.layout.addWidget(self.label)

        self.button = QPushButton("Start Long Task")
        self.layout.addWidget(self.button)

        # 작업 스레드 생성
        self.worker_thread = WorkerThread()
        # 작업 스레드의 진행 상황을 업데이트하는 메서드 연결
        self.worker_thread.progress.connect(self.update_progress)

        # 버튼 클릭 이벤트 연결
        self.button.clicked.connect(self.start_long_task)

    # 버튼 클릭 시 실행되는 메서드
    def start_long_task(self):
        self.label.setText("Working...")
        self.worker_thread.start()  # 작업 스레드 시작

    # 작업 진행 상황을 업데이트하는 메서드
    def update_progress(self, value):
        self.label.setText(f"Task in progress... {value}/5")
        if value == 5:
            self.label.setText("Task completed!")

# 메인 애플리케이션 실행 코드
if __name__ == "__main__":
    app = QApplication(sys.argv)
    window = MainWindow()
    window.show()
    sys.exit(app.exec())

QThread 사용 시 주의할 점

  • GUI 업데이트는 메인 스레드에서만 가능: 백그라운드 스레드에서 직접 GUI를 업데이트하지 않고, 시그널과 슬롯을 이용해 메인 스레드에서 업데이트해야 한다.
  • 스레드 수명 관리: 작업이 끝난 후 스레드를 안전하게 종료하거나, 필요 시 재사용할 수 있도록 관리해야 한다.

Loading script...