PyQt는 Python을 위한 Qt 애플리케이션 프레임워크로, 풍부한 GUI 기능을 제공합니다. 본 강좌에서는 QStackedWidget
을 사용하여 서로 다른 화면 간의 전환을 구현하는 방법을 알아보겠습니다. QStackedWidget
은 서로 다른 위젯을 스택처럼 쌓아두고, 사용자가 필요한 위젯만을 표시할 수 있도록 합니다.
QStackedWidget 개요
QStackedWidget
은 여러 개의 위젯을 겹쳐서 쌓아놓고 사용할 수 있는 컨테이너입니다. 이러한 방식은 여러 화면을 구성할 때 유용하며, 탭 또는 페이지 전환에 적합합니다. QStackedWidget
은 자식 위젯을 인덱스를 통해 구분하고, 특정 인덱스의 위젯만을 표시하게끔 설정할 수 있습니다.
QStackedWidget의 주요 메서드
addWidget(widget)
: 새로운 위젯을 추가합니다.currentWidget()
: 현재 표시되고 있는 위젯을 반환합니다.setCurrentIndex(index)
: 특정 인덱스의 위젯을 표시합니다.setCurrentWidget(widget)
: 특정 위젯을 표시합니다.
실습 예제: QStackedWidget을 이용한 다중 화면 전환
이제 실제 예제를 통해 QStackedWidget
의 사용법을 알아보겠습니다. 이 예제에서는 세 개의 서로 다른 화면을 만들어 버튼 클릭을 통해 전환하는 애플리케이션을 구현합니다.
예제 코드 설명
아래의 코드는 QStackedWidget
을 사용하는 기본적인 PyQt 애플리케이션입니다. 각 화면은 다른 버튼을 통해 전환할 수 있습니다.
import sys
from PyQt5.QtWidgets import QApplication, QMainWindow, QStackedWidget, QWidget, QVBoxLayout, QPushButton, QLabel
class Screen1(QWidget):
def __init__(self):
super().__init__()
layout = QVBoxLayout()
label = QLabel("화면 1")
button = QPushButton("화면 2로 이동")
button.clicked.connect(self.go_to_screen2)
layout.addWidget(label)
layout.addWidget(button)
self.setLayout(layout)
def go_to_screen2(self):
self.parent().setCurrentIndex(1)
class Screen2(QWidget):
def __init__(self):
super().__init__()
layout = QVBoxLayout()
label = QLabel("화면 2")
button = QPushButton("화면 3으로 이동")
button.clicked.connect(self.go_to_screen3)
layout.addWidget(label)
layout.addWidget(button)
self.setLayout(layout)
def go_to_screen3(self):
self.parent().setCurrentIndex(2)
class Screen3(QWidget):
def __init__(self):
super().__init__()
layout = QVBoxLayout()
label = QLabel("화면 3")
button = QPushButton("화면 1로 이동")
button.clicked.connect(self.go_to_screen1)
layout.addWidget(label)
layout.addWidget(button)
self.setLayout(layout)
def go_to_screen1(self):
self.parent().setCurrentIndex(0)
class MainWindow(QMainWindow):
def __init__(self):
super().__init__()
self.setWindowTitle("QStackedWidget 예제")
self.setGeometry(100, 100, 400, 300)
self.stacked_widget = QStackedWidget()
self.screen1 = Screen1()
self.screen2 = Screen2()
self.screen3 = Screen3()
self.stacked_widget.addWidget(self.screen1)
self.stacked_widget.addWidget(self.screen2)
self.stacked_widget.addWidget(self.screen3)
self.setCentralWidget(self.stacked_widget)
if __name__ == "__main__":
app = QApplication(sys.argv)
window = MainWindow()
window.show()
sys.exit(app.exec_())
예제 코드 분석
위 코드는 PyQt5를 이용하여 세 개의 화면을 가진 애플리케이션을 만듭니다. 각 화면(Screen1, Screen2, Screen3)은 QWidget의 서브클래스로 구성되어 있습니다. 각각의 화면에는 QLabel과 다음 화면으로 이동하는 QPushButton이 포함되어 있습니다.
Screen1 클래스
Screen1
클래스는 첫 번째 화면을 구성합니다. QLabel은 “화면 1” 텍스트를 표시하며, 버튼을 클릭하면 go_to_screen2
메서드가 호출되어 setCurrentIndex(1)
로 두 번째 화면으로 전환됩니다.
Screen2 클래스
Screen2
클래스는 두 번째 화면을 구성합니다. 여기에도 QLabel과 버튼이 있으며, 버튼 클릭 시 go_to_screen3
메서드가 호출되어 세 번째 화면으로 전환합니다.
Screen3 클래스
세 번째 화면인 Screen3
에서는 “화면 3” 텍스트가 표시되며, 버튼 클릭 시 go_to_screen1
메서드가 호출되어 다시 첫 번째 화면으로 전환됩니다.
MainWindow 클래스
애플리케이션의 주 창인 MainWindow
클래스는 QMainWindow
를 상속받아 구현됩니다. QStackedWidget
을 초기화하고 각 화면을 추가한 후, 중앙 위젯으로 설정합니다.
다양한 화면 전환 기능 추가하기
이제 기본적인 다중 화면 전환 기능을 구현했으니, 좀 더 복잡한 기능을 추가해 보겠습니다. 예를 들어, 이전 화면으로 돌아가는 버튼이나 다른 버튼으로 화면을 전환하는 기능을 추가할 수 있습니다.
예제 코드 업데이트
아래는 이전 화면으로 돌아가는 버튼이 추가된 업데이트된 코드 예제입니다.
import sys
from PyQt5.QtWidgets import QApplication, QMainWindow, QStackedWidget, QWidget, QVBoxLayout, QPushButton, QLabel
class Screen1(QWidget):
def __init__(self):
super().__init__()
layout = QVBoxLayout()
label = QLabel("화면 1")
button1 = QPushButton("화면 2로 이동")
button2 = QPushButton("화면 3으로 이동")
button1.clicked.connect(self.go_to_screen2)
button2.clicked.connect(self.go_to_screen3)
layout.addWidget(label)
layout.addWidget(button1)
layout.addWidget(button2)
self.setLayout(layout)
def go_to_screen2(self):
self.parent().setCurrentIndex(1)
def go_to_screen3(self):
self.parent().setCurrentIndex(2)
class Screen2(QWidget):
def __init__(self):
super().__init__()
layout = QVBoxLayout()
label = QLabel("화면 2")
button1 = QPushButton("화면 1로 이동")
button2 = QPushButton("화면 3으로 이동")
button1.clicked.connect(self.go_to_screen1)
button2.clicked.connect(self.go_to_screen3)
layout.addWidget(label)
layout.addWidget(button1)
layout.addWidget(button2)
self.setLayout(layout)
def go_to_screen1(self):
self.parent().setCurrentIndex(0)
def go_to_screen3(self):
self.parent().setCurrentIndex(2)
class Screen3(QWidget):
def __init__(self):
super().__init__()
layout = QVBoxLayout()
label = QLabel("화면 3")
button1 = QPushButton("화면 1로 이동")
button2 = QPushButton("화면 2로 이동")
button1.clicked.connect(self.go_to_screen1)
button2.clicked.connect(self.go_to_screen2)
layout.addWidget(label)
layout.addWidget(button1)
layout.addWidget(button2)
self.setLayout(layout)
def go_to_screen1(self):
self.parent().setCurrentIndex(0)
def go_to_screen2(self):
self.parent().setCurrentIndex(1)
class MainWindow(QMainWindow):
def __init__(self):
super().__init__()
self.setWindowTitle("QStackedWidget 예제")
self.setGeometry(100, 100, 400, 300)
self.stacked_widget = QStackedWidget()
self.screen1 = Screen1()
self.screen2 = Screen2()
self.screen3 = Screen3()
self.stacked_widget.addWidget(self.screen1)
self.stacked_widget.addWidget(self.screen2)
self.stacked_widget.addWidget(self.screen3)
self.setCentralWidget(self.stacked_widget)
if __name__ == "__main__":
app = QApplication(sys.argv)
window = MainWindow()
window.show()
sys.exit(app.exec_())
업데이트된 코드 분석
업데이트된 코드에서는 각 화면에 두 개의 버튼을 배치하여 사용자가 원하는 화면으로 쉽게 이동할 수 있도록 했습니다. 이로 인해 사용성이 더욱 향상되었습니다.
화면 1
화면 1에서는 “화면 2로 이동”과 “화면 3으로 이동” 버튼을 통해 다른 화면으로 쉽게 전환할 수 있습니다.
화면 2
화면 2에서도 “화면 1로 이동”과 “화면 3으로 이동” 버튼이 있어 화면 전환이 간편합니다.
화면 3
마지막으로 화면 3에서도 역시 “화면 1로 이동”과 “화면 2로 이동” 버튼이 있어 유연하게 화면 간 전환이 가능합니다.
QStackedWidget 활용 시 고려사항
QStackedWidget
을 사용할 때 몇 가지 고려사항이 있습니다.
- 메모리 사용: 많은 화면을 쌓아둘수록 메모리 사용량이 늘어납니다. 불필요한 화면은 삭제하거나 숨기는 것이 좋습니다.
- UI 성능: 화면 전환이 많아질 경우 UI 반응속도에 영향을 줄 수 있습니다. 필요시 화면 전환 애니메이션 등을 고려할 수 있습니다.
- 접근성: 각 화면에 대한 명확한 항목 표기와 네비게이션 경로를 제공하여 사용자가 쉽게 탐색할 수 있도록 해야 합니다.
결론
이번 강좌에서는 PyQt의 QStackedWidget
을 활용하여 다중 화면 전환 기능을 구현하는 방법에 대해 알아보았습니다. 여러 화면을 쉽게 관리할 수 있는 QStackedWidget
의 특징과 유용성을 직접 체험해 보았으며, 필요한 경우 추가적인 기능을 어떻게 구현할 수 있는지에 대해서도 탐구했습니다.
앞으로도 PyQt를 활용한 다양한 GUI 개발 방법들을 지속적으로 연구하고 시도해 나가시기를 바랍니다. 질문이나 의견이 있으시면 언제든지 댓글로 남겨주세요!