PySide6は、C++のGUIフレームワークQtをPythonから使うための、Qt社公式のバインディング(Qt for Python)です。同じコードでWindows・macOS・Linuxのデスクトップアプリを作れます。検索でよく調べられているのは「商用利用できるのか」「PyQt6と何が違うのか」「インストールと使い方」の3つです。この記事では、2026年10月8日に公開された最新版6.12.0を前提に、ライセンスと商用利用の条件、インストール、最初のGUIアプリ、Qt Designer、exe・appへの配布までを、実際に動かしたコードで説明します。
まとめ:LGPLv3の条件を満たせば商用クローズド配布が可能
PySide6はLGPLv3で使えるため、Qtのライブラリを利用者が差し替えられる形(動的リンク)で同梱し、ライセンス文書の添付やQtのソースの提供といったLGPLv3の条件をすべて満たせば、自社のコードを公開しないまま商用アプリとして配布できます。PyQt6はGPLv3か有償の商用ライセンスしか選べないので、ここが両者の最大の違いです。
ただし注意点が2つあります。1つは、pip install PySide6にはQtChartsやQtGraphsなど、オープンソースではGPLv3でしか使えないモジュールも入っていることです。これらをimportしたアプリは、LGPLのつもりでもGPLの条件がかかります。もう1つは配布物の中身で、公式の配布ツールpyside6-deployの既定設定でビルドすると、Widgetsだけのアプリでも、GPL専用のQt Virtual Keyboardのプラグインが同梱されました。最新版の6.12.0はPython 3.10〜3.15に対応し、pyside6-deployの既定の出力はフォルダ形式(standalone)に変わりました。
PySide6とは|Qt公式のPythonバインディング
PySide6は「Qt for Python」プロジェクトのライブラリで、開発元はQt本体と同じThe Qt Companyです。PySide6のバージョン番号はQt本体と揃っています(PySide6 6.12.0の中身はQt 6.12.0)。バインディングの生成にはShiboken6という自社ツールが使われています。
PySide6の対応機能と付属ツール
業務アプリの部品をそろえたQt Widgetsと、宣言的なUI言語QMLの両方を使えます。データベース接続(QtSql)、ネットワーク、マルチメディア、Webページ表示(QtWebEngine)もモジュールとして入っています。大量データをリアルタイムに描くなら、Qtの上で動く描画ライブラリPyQtGraphのPySide6での使い方が候補になります。
インストールすると、画面設計のpyside6-designer、.uiファイルをPythonに変換するpyside6-uic、リソースを変換するpyside6-rcc、配布用のpyside6-deploy、翻訳用のpyside6-lupdateなど25個のコマンドが入ります(6.12.0で実測)。
最新版6.12.0と対応Pythonのバージョン
2026年10月12日時点の最新版は、2026年10月8日に公開されたPySide6 6.12.0(PyPI)です。対応Pythonは>=3.10, <3.16で、3.10から3.15まで使えます。公式のリリースノートから、使い方に影響する変更を挙げます。
- Python 3.15の初期サポートが入った
pyside6-deployの既定の出力がonefile(単一ファイル)からstandalone(フォルダ)に変わったQtUiTools.loadUiType()はpyside6-uicをPATHから探さなくなった。公式はビルド時にpyside6-uicで変換する方法を推奨している
名前の似たPySide2はQt 5系向けで、PySide6とはモジュール構成やAPIが一部違うため、そのままでは動きません。新しく作るならPySide6を選びます。
PySide6のライセンスと商用利用
PySide6でいちばん多い質問がライセンスです。LGPLの条件を守れば無償で商用利用でき、自社コードも非公開にできますが、条件を知らないと違反になります。OSSライセンスの種類(コピーレフトの強弱)から整理したい場合はOSSのライセンス種別と採用判断を先に読むと全体像がつかめます。
ライセンス構成(LGPLv3・GPLv2・GPLv3・商用)
PyPIでのPySide6のライセンス表記は「LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only」で、このほかにThe Qt Companyの有償の商用ライセンスがあります。Qt for Pythonの商用利用ページは、Qt本体と同じくCommunity Edition(LGPLv3/GPLv3)とCommercial Editionの2系統で配布すると説明しています。どのオープンソースライセンスを選ぶかは利用者が決めるもので、ソースを公開しない商用アプリならLGPLv3を選びます。
商用でソースを非公開にする条件(LGPLv3の義務)
「LGPLだから商用では使えない」は誤解です。LGPLv3が求めるのは、主に次の4点です。
- Qt・PySide6のライブラリを差し替え可能な形で同梱する(利用者がライブラリを変更して再リンクできること。Qt社のLGPLの義務の解説はリバースエンジニアリングの許可まで含めている)
- QtとPySide6をLGPLv3で使っていることを示し、LGPLv3とGPLv3の両方のライセンス全文を添付する(LGPLv3第4項b)
- 使ったQt・PySide6のソースコード(自分で加えた変更を含む)を利用者に渡すか、入手方法を書面で示す。Qt社のオープンソース版のダウンロードページは、提供は配布者の管理下で行う必要があり、Qt ProjectやThe Qt Companyのソースへのリンクだけでは不十分と説明している
- ライブラリの差し替えを封じた機器(いわゆるtivoization)にしない
上の4点は主な義務で、すべてではありません。Qt社も「LGPLv3の要件をすべて満たす限り」アプリのソースを非公開にできると書いています。静的リンクでも、再リンクに必要なオブジェクトファイルなどを渡す方法(LGPLv3第4項d0)はありますが、PySide6のwheelはQtを動的ライブラリとして配っているので、そのまま別ファイルで同梱するのが確実です。
pip install PySide6に入っているGPL専用モジュール
見落とされやすいのがここです。Qt 6のライセンスページは、一部のモジュールをオープンソースではLGPLv3でなくGPLv3だけで提供すると明記しています。PySide6の追加モジュール群(PySide6-Addons)にはその一部が入っており、pip install PySide6だけでimportできてしまいます。6.12.0で実際にimportできたGPL専用モジュールは次のとおりです。
| PySide6のモジュール | 用途 | LGPLで使える代わり |
|---|---|---|
| QtCharts | グラフ(6.10で非推奨) | PyQtGraph・matplotlib |
| QtGraphs / QtGraphsWidgets | 2D・3Dグラフ | PyQtGraph・matplotlib |
| QtDataVisualization | 3Dグラフ(6.10で非推奨) | PyQtGraph(3D表示はOpenGL) |
| QtQuick3D | QMLの3D表示 | Qt 3D(LGPLv3) |
| QtHttpServer | 組み込みHTTPサーバー | Python標準のhttp.server等 |
| QtNetworkAuth | OAuth 2.0 | Python側のOAuthライブラリ |
| QtCanvasPainter | ハードウェア描画の2Dキャンバス | QPainter(QtGui) |
QtChartsとQtDataVisualizationはQtのライセンス一覧ページには載っていませんが、各モジュールのページで「商用ライセンスに加えGPLv3で提供」と書かれています。一覧だけを見て判断しないでください。
ソースを公開しない製品では、これらをimportしないことを機械的に確かめておくと安全です。次のスクリプトは、プロジェクト内の.pyファイルを構文解析して、上の表のモジュールのimport文を見つけたら終了コード1を返します。CIに入れておけば、誰かがQtChartsを足した時点で気づけます。検査するのはimport文とfrom ... import文だけで、importlib.import_module()による動的なimport、QMLファイル内のimport、配布物に入るQtのプラグインは対象外です。配布物の確認は後述の手順で別に行います。
import ast
import pathlib
import sys
# Qt 6.12でオープンソース利用時にGPLv3のみとなるモジュール
GPL_ONLY = {
"QtCanvasPainter", "QtCharts", "QtDataVisualization", "QtGraphs",
"QtGraphsWidgets", "QtHttpServer", "QtNetworkAuth", "QtQuick3D",
"QtVirtualKeyboard",
}
def used_modules(path):
tree = ast.parse(path.read_text(encoding="utf-8"))
for node in ast.walk(tree):
if isinstance(node, ast.ImportFrom) and node.module:
parts = node.module.split(".")
if parts[0] == "PySide6":
if len(parts) > 1:
yield parts[1]
else:
yield from (a.name for a in node.names)
elif isinstance(node, ast.Import):
for a in node.names:
parts = a.name.split(".")
if parts[0] == "PySide6" and len(parts) > 1:
yield parts[1]
root = pathlib.Path(sys.argv[1]) if len(sys.argv) > 1 else None
if root is None or not root.is_dir():
sys.exit("使い方: python gpl_check.py <検査するフォルダ>")
files = list(root.rglob("*.py"))
if not files:
sys.exit(f"{root} に .py ファイルがありません")
hits = []
for p in files:
for m in used_modules(p):
if m in GPL_ONLY:
hits.append(f"{p}: PySide6.{m}")
print("\n".join(hits) or "GPL専用モジュールの import はありません")
sys.exit(1 if hits else 0)
python gpl_check.py srcのように対象フォルダを渡して使います。from PySide6.QtCharts import QChart・from PySide6 import QtGraphs・import PySide6.QtHttpServerを書いたファイルで3件とも検出し、終了コード1になることを確認しました。表のPythonモジュールをそもそもimportできない環境にしたいなら、後述のPySide6-Essentialsだけを入れる方法もあります。ただしEssentialsにも、GPL専用のQt Virtual Keyboardのプラグインは入っています。
商用Qtライセンスが必要になるケース
無償のLGPLで足りないのは、LGPLの条件を満たせないときです。
- QtChartsやQtQuick3DなどGPL専用モジュールを、ソース非公開の製品で使う
- 再リンクに必要なファイルを渡せない、または利用者がライブラリを差し替えられない組込機器に載せるなど、LGPLv3の再リンクの条件を満たせない
- 配布先の規約がLGPLの条件(再リンクの許可など)とぶつかる
- The Qt Companyの技術サポートや、商用向けのLTS版が必要
商用ライセンスを契約した場合は、pip install pyside6で入るCommunity版を使いません。Qt for Pythonの商用利用ページは、ライセンスの問題を避けるため商用ユーザーはCommunity版をpipで入れず、Qtアカウントから入手できる商用パッケージを使うよう案内しています。
PySide6のインストール
PySide6はPyPIからpipで入れます。プロジェクトごとに仮想環境を作ってから入れると、ほかのアプリの依存とぶつかりません。Pythonのバージョンを複数切り替えて使う場合はpyenvでのバージョン切り替え手順も参考になります。
pipでのインストール手順(Windows・macOS・Linux)
python -m venv .venv
# Windowsは .venv\Scripts\activate、macOS・Linuxは source .venv/bin/activate
pip install PySide6
python -c "import PySide6; print(PySide6.__version__)"
最後の行でバージョン(2026年10月12日時点では6.12.0)が表示されれば完了です。この記事と同じ版にそろえたいときはpip install PySide6==6.12.0と版を指定します。公式のパッケージ説明によると、6.3.0以降のPySide6はほぼ空のメタパッケージで、実体は次のパッケージに分かれています。
| パッケージ | 主な中身 | 容量(macOS実測) |
|---|---|---|
| PySide6-Essentials | QtCore・QtGui・QtWidgets・QtQml・QtSql・QtUiTools など | 348MB |
| PySide6-Addons | QtCharts・QtMultimedia・QtBluetooth・QtSerialPort など | ― |
| PySide6_WebEngine | QtWebEngine(ブラウザ部品) | ― |
| PySide6_Pdf | QtPdf | ― |
| PySide6(上の4つすべて) | pip install PySide6 で入る全体 | 1.2GB |
容量は2026年10月にmacOS(universal2のwheel)でduを取った値で、Windows・Linuxでは変わります。このうちQtWebEngineCoreだけで650MBありました。Widgetsの業務アプリならpip install PySide6-Essentialsだけで動き、pyside6-designerやpyside6-uicも入ります。前述のGPL専用モジュールのPythonバインディングはAddons側にあるので、Essentialsだけにすればimportできなくなります(Essentials環境でfrom PySide6 import QtChartsはImportErrorになりました)。ただしこれはPythonから呼べるモジュールの話で、EssentialsにもQt/plugins/platforminputcontextsにGPL専用のQt Virtual Keyboardのプラグインが入っています。配布物のライセンスは、後述の手順で中身を見て確認します。
インストールできない・importできないときの確認
- 対応するバージョンが見つからないと言われる:Pythonのバージョン(6.12.0は3.10〜3.15)か、OS・CPUが対応外の可能性がある。
python --versionを確認し、PyPIのファイル一覧に自分の環境向けのwheelがあるかも見る(6.12.0のmacOS向けwheelはmacOS 14以上が対象) - ModuleNotFoundError: No module named ‘PySide6’:インストールした仮想環境と実行しているPythonが違う。
python -m pip install PySide6のように、実行するPythonで入れ直す - QtWebEngineやQtPdfだけが見つからない:6.12.0から別パッケージ(PySide6_WebEngine・PySide6_Pdf)に分かれた(6.11.1の依存はEssentialsとAddonsだけだった)。
pip install PySide6なら一緒に入るが、Essentialsだけの環境には入らない
PySide6の使い方|最初のGUIアプリの基本構成
PySide6のアプリは、QApplicationを1つ作り、ウィンドウを表示し、app.exec()でイベントループを回すという流れで書きます。以下のコードはすべてPySide6 6.12.0とPython 3.12で実行を確認しました。
ウィンドウを表示する最小のコード
import sys
from PySide6.QtWidgets import QApplication, QLabel
app = QApplication(sys.argv)
label = QLabel("Hello PySide6")
label.setWindowTitle("Sample")
label.resize(240, 80)
label.show()
sys.exit(app.exec())
親を持たないウィジェットは独立したウィンドウになります。実際のアプリではQMainWindowの中に部品を並べます。
シグナルとスロットによるボタン処理の接続
クリックや値の変化といったイベントは「シグナル」、それを受けて動く関数は「スロット」と呼び、connect()でつなぎます。独自のシグナルはSignalで宣言します。次の例はボタンを押すたびにカウンターが増え、その値をシグナルでラベルに渡します。
import sys
from PySide6.QtCore import Qt, QObject, Signal, Slot
from PySide6.QtWidgets import QApplication, QWidget, QLabel, QPushButton, QVBoxLayout
class Counter(QObject):
changed = Signal(int) # int を1つ運ぶ独自シグナル
def __init__(self):
super().__init__()
self.n = 0
@Slot()
def up(self):
self.n += 1
self.changed.emit(self.n)
app = QApplication(sys.argv)
window = QWidget()
layout = QVBoxLayout(window)
label = QLabel("0")
label.setAlignment(Qt.AlignmentFlag.AlignCenter)
button = QPushButton("+1")
layout.addWidget(label)
layout.addWidget(button)
counter = Counter()
button.clicked.connect(counter.up)
counter.changed.connect(lambda v: label.setText(str(v)))
window.show()
sys.exit(app.exec())
ボタンを2回クリックする処理を足して実行し、ラベルが2になることを確かめました。配置はQVBoxLayout(縦)・QHBoxLayout(横)・QGridLayout(格子)に任せると、ウィンドウの大きさを変えても崩れません。数万行の表を出すなら、QTableWidgetより、データをモデルに分けるQTableViewを使います。
Qt Designer(pyside6-designer)による画面設計
画面はコードで組む代わりに、Qt Designerで部品をドラッグ&ドロップして作れます。仮想環境を有効にした状態でターミナルからpyside6-designerを実行すると起動し、作った画面はXML形式の.uiファイルとして保存されます。アプリへの取り込み方は2通りあります。
pyside6-uicによるPythonコードへの変換
公式が推奨しているのはこちらです。.uiからPythonのクラスを生成し、自分のクラスから呼び出します。以下は、Designerの新規作成で「Widget」を選び、最上位のオブジェクト名をFormのまま、入力欄nameEditとボタンokButtonを置いて保存したform.uiを使う例です(「Main Window」を選ぶと生成されるクラス名と基底クラスが変わります)。
pyside6-uic form.ui -o ui_form.py
import sys
from PySide6.QtWidgets import QApplication, QWidget
from ui_form import Ui_Form
class MainWindow(QWidget):
def __init__(self):
super().__init__()
self.ui = Ui_Form()
self.ui.setupUi(self)
self.ui.okButton.clicked.connect(self.on_ok)
def on_ok(self):
print("入力:", self.ui.nameEdit.text())
app = QApplication(sys.argv)
window = MainWindow()
window.show()
sys.exit(app.exec())
生成されたui_form.pyは手で編集せず、画面を直したらpyside6-uicで上書きします。処理はMainWindow側に書くので、画面を作り直してもロジックは消えず、エディタの補完も効きます。
QUiLoaderによる.uiファイルの実行時読み込み
変換せずに、実行時に.uiを読み込むこともできます。
import sys
from PySide6.QtCore import QFile
from PySide6.QtUiTools import QUiLoader
from PySide6.QtWidgets import QApplication
app = QApplication(sys.argv)
ui_file = QFile("form.ui")
if not ui_file.open(QFile.OpenModeFlag.ReadOnly):
sys.exit(f"form.ui を開けません: {ui_file.errorString()}")
loader = QUiLoader()
window = loader.load(ui_file)
ui_file.close()
if window is None:
sys.exit(loader.errorString())
window.okButton.clicked.connect(lambda: print(window.nameEdit.text()))
window.show()
sys.exit(app.exec())
部品にはDesignerで付けたオブジェクト名(window.okButton)でアクセスできますが、補完は効きません。.uiを差し替えるだけで画面を変えたい試作向けです。同じモジュールの関数QtUiTools.loadUiType()は6.12.0で挙動が変わったので、新しいコードでは使わずpyside6-uicに寄せてください。
pyside6-deployによるexe・app化と配布
完成したアプリは、利用者のPCにPythonが無くても動くように実行ファイルにして配ります。PySide6には公式のpyside6-deployが付いており、中ではPythonをC言語に変換してビルドするNuitkaを使います。
pyside6-deploy main.py --dry-run # 実行されるコマンドだけを確認
pyside6-deploy main.py # ビルド(初回は pysidedeploy.spec を作る)
6.12.0で--dry-runを実行すると、Nuitka 4.1.1を入れたうえで--standaloneと--enable-plugin=pyside6を付けてビルドすることが確認できました。前述のカウンターアプリを実際にビルドすると、macOS(Intel)で約3分45秒かかり、72MBの.appができました。設定は初回に作られるpysidedeploy.specに保存され、6.12.0からはpyproject.tomlの[tool.pyside6.deploy]にも書けます。公式ドキュメントは、ビルド時にプロジェクトのモジュールレベルのコードが実行されるため、信頼できるプロジェクトだけを対象にするよう注意しています。PyInstallerやcx_Freezeでも配布でき、PyInstallerにもPySide6用のフックがあります。pyside6-deployはQt公式のツールで、NuitkaのビルドオプションをPySide6向けに組み立てて実行します。
standaloneとonefileの違い(6.12で既定が変更)
| モード | 出力 | 指定方法 |
|---|---|---|
| standalone(6.12からの既定) | Windowsは.distフォルダ内に.exe、macOSは.app | 指定不要 |
| onefile(6.11までの既定) | .exe(Windows)・.bin(Linux)の単一ファイル | –mode onefile |
上のビルドでできた.appの中には、QtCoreやQtWidgetsのライブラリがアプリ本体とは別のファイルとして入っていました。standaloneはQtのライブラリがフォルダ内に別ファイルのまま並ぶので、利用者がライブラリを差し替えられるというLGPLの条件を説明しやすい形です。onefileは配りやすい反面、差し替えの手順を利用者に示しにくくなります。ソース非公開の商用アプリなら既定のstandaloneのまま配ります。macOSは指定に関係なく.appになります。
PySide6配布物のライセンス確認項目
前述のカウンターアプリ(QtWidgetsしか使っていない)を既定設定のpyside6-deployでビルドしたところ、.appの中にGPL専用のQt Virtual Keyboardのプラグインlibqtvirtualkeyboardplugin.dylibが入っていました。pyside6-deployがNuitkaに--include-qt-plugins=platforminputcontextsを渡しており、pysidedeploy.specの[qt]節のpluginsにもplatforminputcontextsが書かれているためです。Pythonのimportを検査しただけでは、これは見つかりません。
find deployment -iname "*virtualkeyboard*" # Windows・Linuxは .dist フォルダ、macOSは .app を指定
macOS用のwheelでは、platforminputcontextsフォルダの中身はこのプラグインだけでした。ソース非公開で配るなら、pysidedeploy.specのpluginsからplatforminputcontextsを外してビルドし直すか、扱いをQt社に確認します。他のOSでは同じフォルダに別の入力用プラグインが入ることがあるので、中身を見てから外し、テスト機で起動と文字入力を確かめてください。
そのうえで、前章のLGPLv3の義務(両ライセンス全文の同梱・自社管理下でのソース提供・ライブラリの差し替え手順)を、配布物ごとに満たしているかを確認します。
配布物に含まれるOSSとそのライセンスを一覧にして管理する考え方はSBOMの目的と作成・運用で解説しています。PySide6を使った業務アプリを要件定義から設計・開発・配布まで任せたい場合は、一創のフルスクラッチ開発でも対応しています。
PySide6とPyQt6・Tkinter・wxPythonの比較
PythonのGUIライブラリは、ライセンスとアプリの規模で選びます。
| ライブラリ | オープンソースのライセンス | ソース非公開の商用配布 | 向いている用途 |
|---|---|---|---|
| PySide6 | LGPLv3 / GPLv2 / GPLv3 | 無償で可(LGPLの条件付き) | 本格的な業務アプリ |
| PyQt6 | GPLv3 | Riverbankの商用ライセンスが必要 | GPLで公開するアプリ |
| Tkinter | PSF License(Tcl/TkはBSD系) | 可 | 小さなツール・学習 |
| wxPython | wxWindows Library Licence | 可 | OS標準の見た目を重視 |
小さな社内ツールならTkinterで足ります。表・ツリー・多言語対応まで要る業務アプリならQt系で、ソースを公開せず無償で配るならPySide6です。Web技術でデスクトップアプリを作る選択肢と比べたい場合はElectronの仕組みと入門も参考になります。
PyQt6とのコード上の違い
PyQt6(2026年10月時点の最新は6.11.0)もQt 6をラップしているため、APIはほぼ同じです。Riverbankの製品ページは「Qtと違い、PyQtはLGPLでは提供されない」と明記しています。コードの差は主に2点で、PySide6 6.12.0とPyQt6 6.11.0で実際に確かめました。
- 独自シグナルの名前:PySide6は
Signal・Slot、PyQt6はpyqtSignal・pyqtSlot。PyQt6でfrom PyQt6.QtCore import SignalはImportErrorになる - 列挙型の書き方:PyQt6は
Qt.AlignmentFlag.AlignCenterのような完全な名前が必須で、Qt.AlignCenterはAttributeErrorになる。PySide6はforgiveness modeで旧来の短い名前も受け付ける
PyQt6から移るときは、PyQt6をPySide6に、pyqtSignalをSignalに置き換えれば多くのコードが動きます。
よくある質問
PySide6は商用利用できますか?
できます。LGPLv3を選び、Qt・PySide6のライブラリを利用者が差し替えられる形で同梱し、LGPLv3とGPLv3の全文の添付やQtのソースの提供などLGPLv3の条件をすべて満たせば、自社のコードを公開せずに商用アプリとして配布できます。QtChartsやQtGraphsなどGPL専用の部品をソース非公開の製品で使う場合や、再リンクできる形で配れない場合は、Qtの商用ライセンスが必要です。
PySide6とPyQt6の違いは何ですか?
どちらもQt 6をPythonから使うためのバインディングで、APIはほぼ同じです。最大の違いはライセンスで、PySide6はLGPLv3でも使えますが、PyQt6はGPLv3かRiverbankの商用ライセンスしかありません。コードでは、独自シグナルの名前(SignalとpyqtSignal)と、列挙型の短い名前を受け付けるかどうかが違います。
PySide6のインストール方法は?
仮想環境を作って有効にし、pip install PySide6を実行します。Essentials・Addons・WebEngine・Pdfの各パッケージがまとめて入り、macOSでは合計約1.2GBになりました。Widgetsだけで足りるならpip install PySide6-Essentialsにすると容量を抑えられます。
PySide6に必要なPythonのバージョンは?
最新の6.12.0はPython 3.10以上・3.16未満で、3.10から3.15まで使えます。3.15は6.12.0で初期サポートが入った段階です。Python 3.9以下では最新版を入れられないため、Pythonを更新してから入れます。
pyside6-designerはどこにありますか?
PySide6をインストールすると、Pythonの実行ファイルと同じ場所(仮想環境のScriptsやbin)にpyside6-designerコマンドが入ります。仮想環境を有効にしてターミナルでpyside6-designerと入力すれば起動します。Qt本体を別にインストールする必要はありません。