✔ Python/4. GUI Programming

[PyQt6] 기본적인 구조부터 이해하기

  • -
주제: PyQt6 기본 구조 이해하기- QApplication, QMainWindow, QWidget, QLabel, QVBoxLayout, QHBoxLayout
작성: 2023-10-24
수정: 2023-10-29

안녕하세요, 루카스입니다.
이번 "PyQt6로 쉽게 GUI 만들기" 시리즈에서는 4개의 글을 통해서 간단한 GUI 구현 및 단계적으로 개념을 소개하고자 합니다.

  🖥️ PyQt6로 쉽게 GUI 만들기
1. 구조 이해 - 2023.10.24 - [✔ Python/4. GUI Programming] - [PyQt6] 기본적인 구조부터 이해하기
2. 코드 구현 - 2023.10.25 - [✔ Python/4. GUI Programming] - [PyQt6] QListWidget 활용한 GUI 구현[1/2] (코드 포함)
3. 코드 개선 - 2023.10.24 - [✔ Python/4. GUI Programming] - [PyQt6] QListWidget 활용한 GUI구현 [2/2] (코드 포함)
4. 테마 적용 - 2023.10.25 - [✔ Python/4. GUI Programming] - [PyQt6] GUI Stylesheet Theme 적용하기 : qt_material 

1. PyQt Main Window?

기본적으로 PyQt을 구성하는 기본창인, QMainWindow부터 알아보도록 하겠습니다. 

QT Main Window Framework(Central Widget)

위의 그림은 전형적인 애플리케이션 창입니다. 일반적인 애플리케이션 창에는 그림에서 볼 수 있듯이 메뉴바, 툴바, 상태바등을 포함하고 있습니다. 이러한 다양한 구성요소들을 커스터마이즈(customized)하여 자신만의 GUI을 생성할 수 있습니다.

  • 메뉴바(Menu Bar): 주요 기능과 명령을 제공하는 메뉴가 포함되어 있으며, 다양한 기능을 탐색하고 실행할 수 있습니다.
  • 툴바(Tool Bar): 자주 사용되는 도구와 명령을 아이콘 또는 버튼 형태로 제공하여 빠른 액세스를 지원합니다. 
  • 상태바(Status Bar): 어플리케이션의 현재 상태나 정보를 표시하는 데 사용됩니다. 

 

2. 기본틀 이해하기

메인 창은 PyQt6 QMainWindow 클래스와 Qt 라이브러리를 사용하여 구현됩니다. 직접 구현해다보면 그 개념 이해가 더 수월합니다. 간단한 PyQt 예제/예시 코드를 통해서 개념을 익혀보도록 하겠습니다.

PyQt6의 기본포맷

2-1.  기본 설정

가장 간단한 PyQt의 기본 코드입니다. 

import sys
from PyQt6.QtWidgets import QApplication, QMainWindow

app = QApplication(sys.argv)
window = QMainWindow()

# 윈도우 기본설정
window.setWindowTitle("pyqt6 위젯적용 테스트")   ## 윈도우 창 제목
window.setGeometry(500, 200, 300, 400)       # #윈도우 위치 및 크기 설정
window.show()

# 애플리케이션 실행
sys.exit(app.exec())

하지만, 필자는 클래스를 활용하여 구현하도록 하겠습니다. 

import sys
from PyQt6.QtWidgets import QApplication,QMainWindow

class MyApp(QMainWindow):
    def __init__(self):
        super().__init__()
        self.initUi()

    def initUi(self) :    
        self.setWindowTitle("pyqt6 위젯적용 테스트")
        self.setGeometry(500,200,300,400)
     
if __name__ == '__main__':
    app = QApplication(sys.argv)
    window = MyApp()
    window.show()
    app.exec()

클래스로 구현한 코드를 보면, "전체 코드 줄 수도 많아지고, 더 복잡해보이는데 왜 굳이 클래스를 쓰려고하지?" 라고 생각하실 수 있습니다. 하지만, 코드가 길어지면서 클래스를 사용하지 않으면, 코드의 가독성은 점점 떨어지게됩니다.
그래서 지금부터는 위와 같은 클래스형태의 코드에 익숙해지시기를 권해드립니다.

 

2-2. 위젯 및 레이아웃 설정

위젯

스마트폰에서 위젯을 추가해서 사용해본적이 있으실겁니다. PyQt에서 언급하는 위젯도 동일한 개념입니다. 다양한 위젯을 위에서 생성한 메인창에 원하는 구역에 추가하는 것입니다. 어떻게 위젯을 구성하고 배치할 것인가를 정하는 것이 바로 레이아웃입니다.

그러면 코드상에서 위젯레이아웃을 한번 추가해보도록 하겠습니다.

import sys
from PyQt6.QtWidgets import QApplication,QMainWindow

class MyApp(QMainWindow):
    def __init__(self):
        super().__init__()
        self.layout = QVBoxLayout()    # 추가
        self.initUi()

    def initUi(self) :    
        self.setWindowTitle("pyqt6 위젯적용 테스트")
        self.setGeometry(200,200,300,400)
       
       ########### 추가 ###############
        layout = self.layout		
        
        widget = QWidget()			
        widget.setLayout(layout)		
        self.setCentralWidget(widget)
       ########### 추가 ###############
     
if __name__ == '__main__':
    app = QApplication(sys.argv)
    window = MyApp()
    window.show()
    app.exec()

레이아웃 (Layouts)

  • 레이아웃은 위젯들을 조직하고 그들의 크기와 위치를 자동으로 관리하는 방법입니다.
  • 레이아웃을 사용하면 다양한 화면 크기와 해상도에서 일관된 사용자 인터페이스를 유지할 수 있습니다.
  • PyQt6에는 여러 유형의 레이아웃이 있으며, 이를 통해 위젯들을 수평, 수직, 그리드, 폼 등 다양한 방식으로 배치할 수 있습니다.

PyQt6 Layout 종류(출처 : https://www.youtube.com/watch?v=Cc_zaUbF4LM)

위젯 (Widgets)

  • 위젯은 사용자 인터페이스에서 사용자와 상호 작용하는 기본 구성 요소입니다.
  • 버튼, 텍스트 박스, 레이블, 슬라이더 등 다양한 유형의 위젯이 있습니다.
  • 위젯은 사용자로부터 입력을 받거나 정보를 표시하는 데 사용됩니다.
  • 위젯은 다른 위젯의 컨테이너 역할을 할 수도 있으며, 이를 통해 복잡한 사용자 인터페이스를 구성할 수 있습니다.

 

2-3. 위젯 적용  - QCheckBox() 

기본 코드에서 위젯의 체크박스를 구현해보도록 하겠습니다. 체크박스는 QtWidgets의 QCheckBox() 임포트하여 구현하시면 됩니다.
구현코드는 다음과 같습니다.

from PyQt6.QtWidgets import QCheckBox # 추가
       
       
       ##########################
        layout = self.layout
        layout.addWidget(QCheckBox()) # 추가
        
        widget = QWidget()			
        widget.setLayout(layout)		
        self.setCentralWidget(widget)
       ##########################

체크박스를 불러오고 해당 체크박스를 layout에 적용하여 표출되도록 합니다.

PyQt 체크박스 생성하기(구현)

 

체크박스 생성외에도 체크가 되었을때, 이를 상태값을 파악할 수 있을까요?

체크박스값은 아래와 값으로 정의되어 있습니다.

  • Qt.CheckState.Unchecked (값 0): 체크되지 않은 상태
  • Qt.CheckState.PartiallyChecked (값 1): 일부만 체크된 상태
  • Qt.CheckState.Checked (값 2): 완전히 체크된 상태
그렇다면, 체크박스가 체크가 된 경우, "Checkbox is checked"라고 표출하고, 그렇지않은 경우에는 "Checkbox is unchecked"라고 표출해보도록 하겠습니다.
    def initUi(self) :    
        self.setWindowTitle("pyqt6 위젯적용 테스트")
        self.setGeometry(3200,10,300,400)

        checkbox = QCheckBox("Check me")
        checkbox.stateChanged.connect(self.checkbox_state_changed)


        layout = self.layout
        layout.addWidget(checkbox)

        widget = QWidget()
        widget.setLayout(layout)
        self.setCentralWidget(widget)
        
    def checkbox_state_changed(self, state):
        print(state)
        if state == 2:
            print("Checkbox is checked")
        else:
            print("Checkbox is unchecked")

간단하게 위와 같이 하드코딩을 해서 구현할 수 있지만, 하지만 아래와 같이 다른 방식으로 구현도 가능합니다.

    def checkbox_state_changed(self, state):
        print(state)
        if Qt.CheckState(state) == Qt.CheckState.Checked :
            print("Checkbox is checked")
        else:
            print("Checkbox is unchecked")
    def checkbox_state_changed(self, state):
        print(state)
        if state == Qt.CheckState.Checked.value :
            print("Checkbox is checked")
        else:
            print("Checkbox is unchecked")

 

2-4. 다수의 체크박스 생성 

체크박스 한개 이상을 생성하고 싶다면?

간단합니다. 여러 개를 생성하면 됩니다.

    def initUi(self) :    
        self.setWindowTitle("pyqt6 위젯적용 테스트")
        self.setGeometry(3200,10,300,400)

        checkbox1 = QCheckBox("Option 1")
        checkbox2 = QCheckBox("Option 2")
        checkbox3 = QCheckBox("Option 3")

        checkbox1.stateChanged.connect(self.checkbox_state_changed)
        checkbox2.stateChanged.connect(self.checkbox_state_changed)
        checkbox3.stateChanged.connect(self.checkbox_state_changed)

        layout = self.layout
        layout.addWidget(checkbox1)
        layout.addWidget(checkbox2)
        layout.addWidget(checkbox3)

        widget = QWidget()
        widget.setLayout(layout)
        self.setCentralWidget(widget)

 

3. 전체 코드

지금까지 진행한 전체코드는 다음과 같습니다.

import sys
from PyQt6.QtCore import Qt
from PyQt6.QtWidgets import QApplication,QCheckBox, QMainWindow,QVBoxLayout,QWidget


class MyApp(QMainWindow):
    def __init__(self):
        super().__init__()
        self.layout = QVBoxLayout()  
        self.initUi()

    def initUi(self) :    
        self.setWindowTitle("pyqt6 위젯적용 테스트")
        self.setGeometry(200,100,300,400)

        checkbox = QCheckBox("Check me")
        checkbox.stateChanged.connect(self.checkbox_state_changed)

        layout = self.layout
        layout.addWidget(checkbox)

        widget = QWidget()
        widget.setLayout(layout)
        self.setCentralWidget(widget)
    
    def checkbox_state_changed(self, state):
        print(state)
        if Qt.CheckState(state) == Qt.CheckState.Checked :
            print("Checkbox is checked")
        else:
            print("Checkbox is unchecked")

if __name__ == '__main__':
    app = QApplication(sys.argv)
    window = MyApp()
    window.show()
    app.exec()

 

4. 다음 포스팅은...?

본 포스팅에서는 기초적인 PyQt6 구현방법에 알아보았습니다. 생각보다 어렵지는 않죠?
그렇다면, 학생이름과 성적이 포함된 데이터가 있을 때, 학생들의 이름을 List로 자동으로 표출하려면 어떻게 할 수 있을까요?
다음 포스팅에서 상세하게 알아보도록 하겠습니다.


해당 포스팅은 "PyQt6로 쉽게 GUI 만들기" 시리즈의 1번째 글입니다.

  🖥️ PyQt6로 쉽게 GUI 만들기
1. 구조 이해 - 2023.10.24 - [✔ Python/4. GUI Programming] - [PyQt6] 기본적인 구조부터 이해하기
2. 코드 구현 - 2023.10.25 - [✔ Python/4. GUI Programming] - [PyQt6] QListWidget 활용한 GUI 구현[1/2] (코드 포함)
3. 코드 개선 - 2023.10.24 - [✔ Python/4. GUI Programming] - [PyQt6] QListWidget 활용한 GUI구현 [2/2] (코드 포함)
4. 테마 적용 - 2023.10.25 - [✔ Python/4. GUI Programming] - [PyQt6] GUI Stylesheet Theme 적용하기 : qt_material 

Reference

  1. 파이썬으로 만드는 나만의 GUI 프로그램 : https://wikidocs.net/book/2165
  2. QT Main Window Framework: https://doc.qt.io/qt-6/qmainwindow.html 
 

PyQt5 Tutorial - 파이썬으로 만드는 나만의 GUI 프로그램

## 소개 - 한국어로 되어있는 PyQt5 자료가 많지 않아서 아래의 여러 튜토리얼과 강의의 예제를 정리하며 시작했습니다. - **PyQt5의 설치**부터 시작해서, **…

wikidocs.net

 

QMainWindow Class | Qt Widgets 6.6.0

 

doc.qt.io


 

728x90
반응형
Contents

포스팅 주소를 복사했습니다

이 글이 도움이 되었다면 공감 부탁드립니다.