파이큐티5 (PyQt5)는 파이썬의 GUI 프레임워크이다.

 

PyQt5는 크로스 플랫폼 GUI 인 QT(큐트)를 파이썬에서 사용할 수 있게끔 바인딩 한 것이다.

 

바인딩이란 말이 좀 어렵다. QT는 C++로 만들어졌는데 다른 언어에서 QT의 라이브러리 기능을 사용하기 위해서는 연결하는 소프트웨어가 필요하다. 타 언어의 라이브러리나 운영체제의 서비스를 사용할 때 사용하는 API가 글루 코드(접착 코드)를 제공하는데 이를 바인딩이라 한다.

 

쉽게 말해 C++ 코드의 GUI 프레임워크를 파이썬에서 사용할 수 있도록 한다는 말이다. 예를 들어 파이썬의 모듈인 Pygame도 C++로 제작된 SDL2 라이브러리를 파이썬에서 구동가능하게 바인딩 한 것이다.

 

파이썬과 C++ 둘다 고수준 언어지만 C++은 저수준에 접근할 수 있기 때문에 파이썬 보다 성능이 훨씬 뛰어나다. 파이썬의 코드로는 성능에 한계가 있다. 만약 파이썬의 코드로 C++의 라이브러리를 조작할 수 있다면 코드는 줄고 성능은 향상되지 않을까? 라는 이유로 바인딩이 개발되었다.

 

WIKIPEDIA에 의하면 PyQT5는 440개의 클래스들에 무려 6,000여개의 함수와 메소드를 구현했다. 역사가 오래된 회사에 의해 개발되다보니 쌓인 노하우가 많다. 

 

워낙 기능이 많지만 다음의 내용을 포함한다. 그냥 하나의 GUI 프레임워크가 떨어져 있는게 아니라 협동할 수 있는 프레임워크들을 모아 높은 것이다.

 

  • 그래픽 유저 인터페이스 (GUI) 위젯, OpenGL
  • 클래스로 SQL 데이터 베이스 (ODBC, MySQL 등)
  • 네트워크, 웹 툴킷
  • XML 파서
  • QScintilla 기반의 텍스트 에디터 위젯
  • SVG 백터 그래픽 지원

오픈 소스이긴 하지만 상업용은 별도 라이센스를 구매해야 한다. GPL 같은 조건들이 포함되어 있으므로 배포시에는 라이센스의 내용을 확인해야 한다. PyQt의 라이센스는 Riverbank Computing 이 관리하는데 아래의 FAQ는 라이센스에 상세 내용을 볼 수 있다.

 

파이큐티5의 학습 난이도는 파이썬 스크립트를 어느 정도 작성할 수 있는 사람에게 적당하다. GUI 프레임워크 중에서는 상급에 해당한다.  좀더 편안한 기술 트리를 타고 싶다면 PyQt5 를 사용하기전에 tkinter 로 계산기 정도를 만들어 보고 PyQt5에 도전하는 것을 권장한다.

 

Riverbank Computing | License FAQ 파이큐티5 제작사

 

Riverbank Computing | License FAQ

License FAQ Here we use the term proprietary application to mean any application that is distributed under the terms of a license that is not compatible with the relevant version of the GPL and has been developed using a copy of any sofware licensed under

www.riverbankcomputing.com

 

파이큐티는 워낙 기능이 막강해서 해외에서는 항상 파이썬의 Best GUI 로 선정되고 있다. 한국에서 대중적으로 알려지기 시작한 것은 파이썬의 인기가 높아진 최근의 일이다.

 

파이큐티의 버전은 크게 나눠서 PyQt4와 PyQt5 가 있다. PyQt5는 파이썬3만 지원을 한다. 지금 새로 시작하는 입장이면 PyQt5를 배우는게 좋을 것 이다. 양쪽을 다 지원하는 qtpy 라는 모듈도 있는데 그냥 알아만 두면 될 것 같다.

 


항상 그렇듯이 새로운 언어를 배울 때는 Hello World 부터 시작이다.

 

PyQt5 모듈로 아래의 창을 만들어 본다.

 

 

PyQt5의 설치 자체는 다른 프레임워크에 비해서 어렵지 않다. pip 명령어를 사용한다.

pip install pyqt5

 

* 다음은 Hello World의 전체 코드이다. Tkinter에 비하면 좀 길다. 사실 코드를 더 줄일 수도 있는데 그렇게 하면 GUI화면은 너무 볼품이 없어서 폰트와 레이아웃을 넣다보니 몇줄이 더 들어간다.

 

from PyQt5.QtWidgets import QWidget, QApplication, QLabel, QVBoxLayout
from PyQt5.QtCore import Qt
from PyQt5 import QtGui
import sys


class Window(QWidget):
    def __init__(self):
        super().__init__()
        self.setGeometry(300, 300, 400, 300)
        self.setWindowTitle("Python PyQt5")

        self.label = QLabel("Hello World!")
        self.label.setFont(QtGui.QFont('Hack', 20))

        layout = QVBoxLayout()
        layout.addWidget(self.label, alignment=Qt.AlignCenter)
        self.setLayout(layout)


app = QApplication(sys.argv)
root = Window()
root.show()

sys.exit(app.exec_())

 

* GUI 프로그래밍을 하면서 윈도우를 하나 만드것이 얼마나 복잡한지 알게 된다. 당연히 CLI 환경에서 표준입출력을 사용하는 것 보다는 복잡하다.

 

콘솔에서는 별로 따질게 없다. 운영체제의 서비스를 사용하기 때문이다. 운영체제를 부르는 것(System Call)만으로도 충분하다.

 

한편 GUI의 G는 Graphic의 약자이다. 윈도우의 그래픽은 root 윈도우 메뉴바, 프레임, 레이블, 버튼 등 기본으로 제공하는 클래스만 해도 백가지가 넘어가는데 거기다 이벤트 리스닝와 처리 등을 고려하면 수백가지의 설정을 해줘야 한다. 하나만 설정이 틀려도 프로그램은 종료한다.

 

초기 GUI 프로그래밍인 Win32 프로그램을 만드는 코드만 해도 거의 200줄이 된다. (아래 포스트 참고) 그것에 비하면 PyQt5는 코드를 상당히 깔끔하게 정리해놨다고 볼 수 있다. 그러면서도 C++의 능력을 사용할 수 있게 글루코드를 제공하는 것이 바인딩이라고 했다.

(프레임워크가 하는 많은 일의 상당수는 일단 교통 정리 하는 일이다)

 

C++ Win32 GUI 프로그래밍 윈도우 창 만들기, 텍스트 출력, 도형그리기 (tistory.com)

 

C++ Win32 GUI 프로그래밍 윈도우 창 만들기, 텍스트 출력, 도형그리기

C++ 윈도우 프로그래밍의 고전은 Win32 GUI 다. 지금이야 웹과 모바일앱의 전성시대 유튜브 시대를 맞이하여 윈도우 프로그래밍에 대해 진지하게 생각하지 않아도 된다. 웬만한 기술들은 웹브라우

digiconfactory.tistory.com


그럼 튜토리얼의 정석대로 PyQt5 첫 코드를 리뷰해보자. 우선 여러가지 모듈, 클래스들을 import 해야한다.

 

여기서 눈여겨봐야 할 것은 QWidget 이다. Q를 앞에 붙인 것은 QT 제품라인이라는 것을 알 수 있게 하기 위해서다.

 

자바 언어의 경우 최초의 GUI 클래스에는 Frame 이라는 일반 명사를 썼다가 나중에 JFrame 이라는 식으로 접두사를 붙였다. 일반 명사를 써버리면 다음에 쓸 이름이 부족해지기 때문에 접두사를 붙인다.

 

 

Widget 위젯이란 쉽게 말해 레이블, 버튼같은 것들을 말한다. 사용자가 직접 보고 조작하는 단위이기 때문에 사용자 경험(UI)에 있어서 중요한 요소다.

다른 것들은 부가적으로 import 했지만 QWidget 과 QApplication 모듈이 없으면 윈도우의 생성을 할 수 없다.

 

클래스 이름을 Window 라고 지으면서 QWidget 을 상속했다. super().__init__() 는 현재 클래스가 QWindow의 객체임을 선언한다. geometry 같은 윈도우 메소드 설정을 사용할 수 있게 한다.

 

이것은 QWidget 을 상속해서 윈도우를 만들 때 필요한 절차라고 보면 된다. 파이썬의 프레임워크 중에는 이런 식으로 초기화를 하는 방법을 많이 사용한다. 보이지 않지만 PyQt5 프레임워크에서 부모 클래스의 생성자가 GUI를 생성하는 많은 코드를 처리해주는 것이다.

 

나머지 메소드들은 tkinter GUI를 해봤다면 크게 어렵지 않을 것이다. geometry 는 먼저 윈도우가 시작되는 좌표와 너비, 높이로 생성되고 Title 은 타이틀이다. 레이블에 Q자가 붙은 것을 보면 PyQt는 접두어로 모두 Q를 붙인다. 다음은 Font 슬 설정하는 코드이다.

 

이미 PyQt5에 적응되는 기분이 든다.

 

레이아웃은 보통 VBox 가 들어가면 수직, HBox가 들어가면 수평 레이아웃이다.

 

레이아웃에 위젯을 추가하고 다시 레이아웃을 QWidget (메인 윈도우 클래스)에 추가한다. 전체적으로 연결이 된다.

 

* 메인윈도우 -> 레이아웃 -> 위젯

 

의 심플한 구조다. 단지 각각의 속성들을 설정하는 과정이 사이에 추가될 뿐이다. 대부분의 GUI 프로그래밍에서 이 과정은 비슷하다. 우리가 코드를 실행하면 PyQt라는 이름의 공장에서 윈도우를 조립을 지시하는 일이라 생각해보자. 윈도우 창을 하나 만들기 위해서 전체 설계를 하고 창틀을 제조해서 거기에 레이블도 붙이고, 버튼도 붙이고 배치방법(레이아웃)도 결정해서 최종적으로 하나의 윈도우창을 만든다.

 

공장에서 일을 해봤다면 이 일이 결코 쉬운 것이 아님을 알 수 있을 것이다. 그런데 프로그래머들은 모듈의 힘을 빌려 쉽게 할 수 있다.

 

사람들은 수레바퀴를 발명하지 않아도 멀리까지 갈 수 있다. 

 

don't reinvent the wheel just realign it (수레바퀴를 다시 발명하지 말고 그것을 재조정해라)

 

이 말을 해외에서는 많이 인용하는데 한국에서는 잘 하지 않는 말이다. 아무래도 남이 만들어 놓은 발명한 것을 마음대로 이용하는 것에 대해 조심하는 문화가 있는게 아닐까 싶다.

 

서양의 역사가 최근까지 꽤 오랫동안 전쟁과 정벌을 일삼을 것을 생각하면 어쩌면 그들은 당연하게 생각하는 것일지 모르겠다. 하지만 한국도 실리콘 밸리에 진출한 엔지니어들을 보면 비슷한 마인드를 갖고 있는 것 같다. 아마 실리콘 밸리의 흥망성쇄를 보면서 한국에서 가지고 갔던 그들의 멘탈도 바뀌는 것 같다.

 

GUI를 이야기 하면서 잡설이 길어진다. GUI를 사용하는 과정이 대부분 비슷하기 때문이다.

(좋은 튜토리얼로 만들기 위해 나중에 잡설은 분리될 수 있다)

 

 

마지막 부분은 QyQt5의 구조를 보여준다. QApplication 은 무한루프를 반복하는 응용프로그램을 만들어낸다. 무한루프라서 헷갈릴 필요는 없다. 기본적으로 모든 윈도우는 무한루프 while (1) 를 돈다. 사용자가 어떤 동작을 취하는 것을 듣는 것을 리스닝 Listening (듣다)이라고 하고 들은 내용을 해석해서 처리하는 것을 액션 Action 이라고 한다.

 

QApplication 이 하는 것은 이 무한루프 구조를 만들어 내는 것이다. 즉 콘트롤러이다. app 인스턴스의 메소드 exec가 sys.exit ( ) 안에 들어가 있다. 즉 무한루프가 종료되었을 때 시스템을 종료시키는 코드이다.

 

무한루프는 사용자나 운영체제가 종료시킬 수 있다. 보통은 break 문을 사용해서 탈출하는데 이것들은 QApplicaiton 의 인스턴스를 통해서 조작할 수 있다. 그런 부분이 애플리케이션 프로그래머가 해야할 일이다.

 

root 인스턴스는 Window 클래스 즉 QWidget 이다. 이 부분은 보이는 부분이다. 보이는 부분이지만 이벤트가 발생했을 때 QApplication 과 함께 처리하고 업데이트 하는 클래스이다. 하위 위젯들을 데리고 있으니까 이들을 show 메소드로 메모리에서 화면으로 옮기는 것이다. 그 후에는 무한루프의 update 를 통해서 화면에 유지되는 것이다.

 

파이큐티의 Hello World 프로그램을 만들어 보면서 전체의 흐름과 구조를 익히면 충분하다. 처음에 디자이너를 사용해서 편하게 만들 수도 있지만 좀 더 깊이 있게 알고 싶다면 코드로 작성해보는 것을 권장한다. 디자이너를 사용하게 되면 코드는 들여다 보지 않게 되니까 가급적 처음에 코드를 마스터하는 것이 좋다.

 

 

* 참고: QT는 큐트라고 말하는데 PyQt의 경우 파이큐티라고 부르는게 많다.

 


기타사항

*가장 짧은 코드로 만드는 PyQt5 윈도우창. 모든 값이 Default로 만들어진다. 코드 7줄로 만들 수 있다. 윈도우의 생성자를 바깥에서 호출해버린다.

from PyQt5.QtWidgets import QMainWindow, QApplication
import sys
app = QApplication(sys.argv)
mainScreen = QMainWindow()
QMainWindow.__init__(mainScreen)
mainScreen.show()
sys.exit(app.exec_())


* 가장 기본적인 코드 Q윈도우와 Q애플리케이션만 사용. 정상적으로 클래스 안에서 생성자 호출해서 사용. 부모의 생성자는 super()로 호출해도 되고 직접 QMainWindow를 사용해도 된다.

from PyQt5.QtWidgets import QMainWindow, QApplication
import sys


class Window(QMainWindow):
    def __init__(self):
        QMainWindow.__init__(self)
        self.setGeometry(300, 300, 400, 300)
        self.setWindowTitle("First Window PyQt5")


app = QApplication(sys.argv)
window = Window()
window.show()

sys.exit(app.exec_())

 

* 위젯만 출력하면 더 짧은 코드로 가능하다. 여섯줄이다.

from PyQt5.QtWidgets import QApplication,QLabel
import sys
app = QApplication(sys.argv)
label = QLabel("Hello World")
label.show()
sys.exit(app.exec_())

레이블 위젯

 

kayken7/PyQt5-tutorial (github.com)

 

kayken7/PyQt5-tutorial

Contribute to kayken7/PyQt5-tutorial development by creating an account on GitHub.

github.com

공유하기

facebook twitter kakaoTalk kakaostory naver band