PyQt6에서 PySide6으로 환승

개요

PyQt6PySide6API (Application Programming Interface)가 90% 이상 똑같습니다.

import 경로 정도만 바꾸면 대부분의 코드가 그대로 돌아갈 정도죠.


그런데 딱 하나, 라이선스만큼은 절대 똑같지 않습니다.

그리고 이 차이는 "취향" 문제가 아니라, 여러분이 만든 앱을 배포할 수 있느냐 없느냐를 가르는 현실적인 문제입니다.


사실 저도 PyQt5 버전까지는 PySide5를 고려해 본적이 별로 없었지만,

코드의 배포성을 고려할때, 앞으로 PySide6을 사용하려 합니다.

[ PyQt6에서 PySide6으로, ChatGPT 생성]

갈아타는 이유

왜 신규 프로젝트라면 PySide6 쪽으로 갈아타는 걸 추천하는지 정리해보겠습니다.


1. 라이선스, 이게 진짜 핵심

[PyQt6 vs PySide6 라이선스 비교]

PyQt6는 GPL v3 라이선스입니다.

GPL은 대표적인 카피레프트 라이선스라,

GPL로 라이선스된 라이브러리를 써서 만든 프로그램을 외부에 배포하는 순간 내 프로그램의 소스코드도 공개해야 하는 의무가 생깁니다.

따라서 GPL 라이선스 조건과 호환되지 않는 형태로 PyQt6를 사용해 독점적인 상용 프로그램을 배포하려면, Riverbank의 상용 라이선스를 별도로 고려해야 합니다.

(개발자 1인 좌석당 별도 과금).

회사에서 만든 프로그램을 고객사에 납품하거나, 소스코드를 감추고 싶은 상용 프로그램을 만들 계획이라면 이 조건은 치명적입니다.


반면 PySide6는 LGPL v3/GPL v3Qt 상용 라이선스입니다.

LGPLGPL보다 훨씬 관대해서, PySide6 라이브러리 자체를 수정하지 않고 그냥 가져다 쓰기만 한다면 내 애플리케이션의 소스코드를 공개할 의무가 없습니다.

LGPL 조건을 준수할 수 있다면 PySide6을 이용해 소스코드를 공개하지 않는 상용 프로그램을 배포하는 것도 가능합니다.

다만 LGPL 역시 단순히 "소스코드를 공개하지 않아도 된다"는 의미는 아닙니다.

사용 방식과 배포 형태에 따라 라이선스 고지, 라이브러리 교체 가능성 등의 조건을 준수해야 합니다.


즉, 폐쇄형 상용 프로그램으로는 자유롭게 배포할 수 있다는 뜻이죠.

게다가 개발사가 Qt를 직접 만드는 The Qt Company 라서, 향후 Qt 코어 API 변화에 대한 대응도 더 빠른 편입니다.

(사실 PySide가 Qt(C++)의  원 제작사 임에도 과거에는 버그, 편의성, 성능이 PyQt보다 떨어졌음, 현재는 동등)

정리하면, "팔 수 있는 앱"을 만들 계획이라면 PySide6 쪽이 훨씬 안전합니다.

사이드 프로젝트, 사내 툴, 오픈소스라서 소스코드 공개에 아무 거리낌이 없다면 PyQt6도 무방하지만, 조금이라도 상용 or 비공개 가능성이 있다면 처음부터 PySide6으로 시작하는 편이 마음 편합니다.


카피레프트(Copyleft)는 저작물을 누구나 자유롭게 사용, 수정, 배포할 수 있도록 허용하되, 파생 저작물 역시 원본과 동일한 조건(자유로운 공유)으로 배포해야 하도록 규정하는 법적 기법이자 철학.


GPLv3 vs LGPLv3 비교

구분 GPLv3 LGPLv3
정식 명칭 GNU General Public License v3 GNU Lesser General Public License v3
기본 성격 강한 Copyleft 약한 Copyleft
주된 용도 프로그램 전체 라이브러리
라이브러리 사용 결합된 프로그램에도 GPL 조건이 적용될 수 있음 라이브러리를 사용하는 프로그램은 독점 라이선스로 배포 가능
내 프로그램 소스 공개 GPL 코드를 결합하여 배포하는 경우 소스 공개 의무가 발생할 수 있음 LGPL 라이브러리를 사용하는 프로그램 자체의 소스 공개는 일반적으로 요구하지 않음
라이브러리 수정 수정한 GPL 코드 배포 시 GPL 조건 적용 수정한 LGPL 라이브러리는 LGPL 조건에 따라 배포해야 함
상용 프로그램 가능하지만 GPL 조건 준수 필요 상용·독점 프로그램에서 사용하기 상대적으로 용이
정적 링크 GPL 조건이 강하게 적용됨 가능하지만 재링크 등의 LGPL 조건을 고려해야 함
동적 링크 (DLL/SO) 결합된 프로그램에 GPL 조건이 적용될 수 있음 독점 프로그램에서 LGPL 라이브러리를 사용하는 것이 일반적으로 가능
다른 라이선스와의 결합 제약이 비교적 큼 상대적으로 자유로움
대표적인 사용 상황 프로그램 자체를 자유 소프트웨어로 유지하고 싶을 때 여러 프로그램에서 사용할 수 있는 라이브러리를 만들 때


핵심 요약

  • GPL v3: "이 코드를 조금이라도 가져다 쓰면(링크하면) 전체를 공개해야 한다" — 전파력이 강함
  • LGPL v3: "라이브러리 자체는 공개해야 하지만, 그냥 갖다 쓰는(링크하는) 프로그램까지 공개할 필요는 없다" — 상용 소프트웨어와의 호환성을 높인 버전

즉, LGPL v3는 GPL v3의 강한 전파력을 완화해서 비공개 소프트웨어에서도 라이브러리 형태로 자유롭게 사용할 수 있게 만든 라이선스라고 보시면 됩니다.

다만 라이브러리 자체를 수정한 경우에는 그 수정본은 LGPL로 공개해야 합니다.


2. 그 외 PySide6이 유리한 이유들

  • Qt DesignerPySide6 설치시 기본 포함.
  • pip install pyside6만 하면 pyside6-designer가 같이 설치.  (PyQt6는 Designer 앱이 패키지에 없어서 별도 설치, 완전 불편)
  • 리소스 컴파일러(pyside6-rcc) 제공. (PyQt6는 pyrcc6가 빠져서, 아이콘 리소스를 쓰려면 번거로운 우회가 필요)
  • Qt 공식 지원, PySide6은 Qt 프레임워크를 직접 만드는 회사가 배포, 신규 Qt 버전 대응이나 장기 지원 측면에서 안정적


3. *.ui 파일 로드 코드 비교

Qt Designer에서 생성한 *.ui 을 코드에서 불러와 사용하는 경우,

PyQt6PySide6 대비 코드 작성이 편리해 PySide6는 별로 사용해 본 적이 없습니다.😕

그래서 PySide6에서 대응법을 정리해 둡니다.


PyQt6

from PyQt6.QtWidgets import QApplication, QWidget
from PyQt6 import uic
import sys

class Window(QWidget):

    def __init__(self):
        super().__init__()

        uic.loadUi("form.ui", self)
        self.pb.clicked.connect(self.onClick)

    def onClick(self):
        print('pressed!')

if __name__ == '__main__':
    app = QApplication(sys.argv)
    w = Window()
    w.show()
    sys.exit(app.exec())
  • PyQt6는 uic.loadUi(path, self) 한 줄로 위젯이 self에 바로 병합.


PySide6

from PySide6.QtWidgets import QApplication, QWidget
from PySide6.QtUiTools import QUiLoader
from PySide6.QtCore import QFile
import sys

class Window(QWidget):

    def __init__(self):
        super().__init__()

        loader = QUiLoader()
        ui_file = QFile("form.ui")
        ui_file.open(QFile.OpenModeFlag.ReadOnly)
        self.ui = loader.load(ui_file, self)
        ui_file.close()        

        self.ui.pb.clicked.connect(self.onClick)

    def onClick(self):
        print('pressed!')

if __name__ == '__main__':
    app = QApplication(sys.argv)
    w = Window()
    w.show()
    sys.exit(app.exec())
  • PySide6QUiLoader가 위젯 트리를 별도로 반환해서 self.ui를 거쳐 접근.


코드량은 PySide6이 살짝 더 길지만,

라이선스 이점을 생각하면 이 정도 번거로움은 충분히 감수할 만합니다.


4. 그래도 PyQt6이 남아있는 이유

물론 PyQt6도 장점이 있습니다.

PySide가 삽질하는 사이, 사용되어진 역사가 길어 온라인 자료, 예제, 스택오버플로우 답변이 압도적으로 많고,

uic.loadUi(path, self)처럼 코드가 더 짧은 부분도 있습니다.

이미 GPL 조건에 문제없는 오픈소스, 학습용 프로젝트를 진행 중이라면 굳이 지금 갈아탈 필요는 없습니다.


하지만 새 프로젝트를 시작하는 시점이라면,

나중에 "이 프로그램을 팔아야 하나?" 같은 고민이 생겼을 때 라이선스 문제로 발목 잡히지 않도록, 처음부터 PySide6으로 시작하는 걸 추천드립니다.


마무리

정리하면, 

  • API는 사실상 쌍둥이 수준으로 비슷하다.
  • 따라서, PyQt를 사용한다면 PySide를 배우는 부담은 거의 제로.
  • 그러나 라이선스는 하늘과 땅 차이 — PyQt6GPL/상용, PySide6LGPL
  • 상용 앱, 배포 앱을 염두에 둔다면 PySide6이 훨씬 안전한 선택


지금 신규 프로젝트를 고민 중이라면, 이번 기회에 PySide6으로 갈아타 보는 건 어떨까요 😊.


궁금한 점은 댓글로, 감사합니다.

댓글

이 블로그의 인기 게시물

Qt Designer 설치하기

파이썬을 활용한 PID 제어기 GUI 구현

MFC기반 화면 캡쳐앱 만들기