/ PROGRAMMING, PYTHON, GUI

PyQt6을 이용하여 파이썬으로 GUI 어플리케이션 만들기

파이썬으로 GUI 어플리케이션을 만들어 보자.

PyQt 정보

Qt는 GUI 어플리케이션에 관련된 고급(high-level) API를 구현한 크로스 플랫폼 C++ 라이브러리 집합이다. PyQt는 C++ 대신 Python을 언어로 사용하여 Qt 라이브러리를 이용한 어플리케이션 개발이 가능하도록 하는 Python 라이브러리이다.


라이브러리 설치

pip install QtPy

PyQt5/PySide2/PyQt6/PySide6 를 통합 설치해주는 추상화 레이어 라이브러리인 QtPy 를 설치한다.

어플리케이션 생성

import sys
from PyQt6.QtWidgets import QApplication, QWidget

class MyApp(QWidget):

    def __init__(self):
        super().__init__() #QWidget()
        self.initUI()

    def initUI(self):
        self.setWindowTitle('app')
        self.move(300,300)
        self.resize(1600,900)
        self.show()

def main():
    app = QApplication(sys.argv)
    window = MyApp()

    # Start the event loop
    sys.exit(app.exec_())

if __name__ == '__main__':
    main()

위 예제 코드에서는 QWidget 클래스를 상속하는 MyApp 클래스를 생성하여, QWidget 에서 제공하는 메소드를 사용해 GUI 창을 생성하였다.

이때 show() 메소드를 실행하지 않으면 창이 실제로 보여지지 않는다.

QApplicationQWidget

from PyQt6.QtWidgets import QApplication, QWidget

각각 PyQt에서 제공하는 QtWidgets 모듈의 클래스에 해당한다.

Qt의 메인 모듈은 QtWidgets, QtGui, QtCore 이다.

QApplication : 어플리케이션 handler

QWidget : 기본 GUI 위젯

app = QApplication(sys.argv)

QApplication의 인스턴스를 생성하고 쉘의 argument를 넘겨준다.

window = MyApp()

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

QWidget을 상속한 MyApp의 인스턴스를 생성한다. Qt가 객체 설정을 진행할 수 있도록 super __init__() 함수를 반드시 호출해줘야 한다.

Qt에서 모든 최상위단의 위젯은 ‘창(window)’에 해당한다. 즉, 창으로 표현되는 위젯은 부모를 갖지 않으며 다른 위젯이나 레이아웃 내에 감싸지지 않는다. MyApp 클래스는 QWidget 을 상속했으므로 처음 생성된 인스턴스 window는 최상위단 위젯에 해당한다.

NOTE

parent가 없는 위젯은 기본적으로 invisible하다. 따라서, window 인스턴스가 생성된 후에는 반드시 .show() 메소드를 호출하여 창이 보이도록 한다.

event loop 을 시작하기 위해 app.exec() 을 호출한다.

Evnet loop에 대한 설명

모든 Qt 어플리케이션의 핵심은 QApplication 클래스이다. 모든 어플리케이션이 동작을 위해 단일의 QApplication 객체를 필요로 한다. 이 오브젝트는 어플리케이션의 event loop 을 관리한다.

위젯 (Widgets)

QMainWindow

Qt에서는 어떤 위젯이든 최상위단에서 창으로 구현될 수 있으므로, 예를 들면 QWidgetQPushButton으로 바꿀 경우 하나의 클릭 가능한 버튼이 있는 창이 생성될 것이다.

위의 코드에서 수정하면 MyAppQWidget이 아닌 QPushButton을 상속하도록 하면 될 것이다.

class MyApp(QPushButton):

그러나 보통의 경우 이런 식으로 코드를 작성하지 않는다. 위젯 내에 다른 위젯들을 감쌀 수 있다는 레이아웃 구조의 특징을 이용해, 일반적으로 비어 있는 QWidget 내에 복잡한 UI를 쌓아 올린다.

QMainWindow 위젯은 툴바, 메뉴, 상태 바, dockable한 위젯들을 포함하는 스탠다드한 창 기능들을 제공하는 pre-made 위젯이다.

class MyApp(QMainWindow):

처음에는 QMainWindow의 인스턴스를 생성하면 이전과 같이 빈 창만 나올 것이다.

MyApp 클래스를 통해 창에 다른 위젯들을 추가하면 된다.

import sys
from PyQt6.QtWidgets import QApplication, QWidget, QMainWindow, QPushButton

class MyApp(QMainWindow):

    def __init__(self):
        super().__init__() #QWidget()
        self.initUI()

    def initUI(self):
        button = QPushButton("Press Me!")
        self.setCentralWidget(button)
        self.show()

def main():
    app = QApplication(sys.argv)
    window = MyApp()

    # Start the event loop
    app.exec()

if __name__ == '__main__':
    main()

QPushButton 위젯을 생성 후, QMainWindow.setCentralWidget 메소드로 QMainWindow 내에 버튼 위젯을 배치할 수 있다.

창 크기 조절 및 다양한 위젯들

현재 우리가 만든 프로그램의 창은 자유롭게 리사이징이 가능하다.

Qt에서는 QtCore 모듈에서 제공하는 QSize 오브젝트에 의해 창 크기가 정의되는데, 이것은 가로 길이(width) 와 세로 길이 (height)를 각각 순서대로 parameter로 받는다.

이 오브젝트와 QMainWindow의 메소드를 통해 창 크기를 제한할 수도 있다. 예를 들어, 다음 코드는 400x300 크기로 제한된 창을 생성한다.

import sys

from PyQt6.QtCore import QSize, Qt
from PyQt6.QtWidgets import QApplication, QWidget, QMainWindow, QPushButton

class MyApp(QMainWindow):

    def __init__(self):
        super().__init__() #QWidget()
        self.initUI()

    def initUI(self):
        button = QPushButton("Press Me!")
        self.setFixedSize(QSize(400,300))
        self.setCentralWidget(button)
        self.show()

def main():
    app = QApplication(sys.argv)
    window = MyApp()

    # Start the event loop
    app.exec()

if __name__ == '__main__':
    main()

.setMinimumSize() 메소드와 setMaximumSize() 메소드로 창의 최소 크기나 최대 크기를 제한할 수도 있다.

위와 같은 크기 관련 메소드는 어떠한 위젯에도 사용 가능하다.


참고 문헌