MochiuWiki : SUSE, EC, PCB
案内
メインページ
最近の更新
おまかせ表示
MediaWiki についてのヘルプ
ツール
リンク元
関連ページの更新状況
特別ページ
ページ情報
We ask for
Donations
検索
個人用ツール
ログイン
Toggle dark mode
名前空間
ページ
議論
表示
閲覧
ソースを閲覧
履歴を表示
Qtその他 - PyQt5とPySide2のソースを表示
提供: MochiuWiki : SUSE, EC, PCB
←
Qtその他 - PyQt5とPySide2
あなたには「このページの編集」を行う権限がありません。理由は以下の通りです:
この操作は、次のグループのいずれかに属する利用者のみが実行できます:
管理者
、new-group。
このページのソースの閲覧やコピーができます。
== 概要 == Qt5でPythonの開発環境を構築する時、PyQt5とPySide2の2種類が存在する。<br> <br> ここでは、2種類のいくつかの差異を確認して、両方でシームレスに機能するサンプルコードを作成する手順を記載する。<br> これらを理解することにより、PyQt5の例からPySide2で動作するようにに変換することができる。<br> <br><br> == 歴史 == PyQt5とPySide2の2種類のパッケージが存在する理由を記載する。<br> <br> PyQtは、Riverbank Computing社のPhilThompsonによって開発されている。<br> 2009年にQtツールキットを所有していたNokiaは、Qt用のPythonバインディングをLGPLライセンス(Qtと同様)で利用できるようにしたいと考えていた。<br> Riverbank社と合意することができず、彼らはPySideとして独自のバインディングをリリースした。<br> <br> 2種類のインターフェースは最初は同等だったが、PySideの開発は最終的にPyQtに遅れをとっていた。(Qt5のリリース後に特に顕著だった)<br> PyQt5は2016年半ばから利用可能であったが、PySide2の最初の安定したリリースは2018年からである。<br> Qt5を使用したPythonの例の多くが、PySide2ではなくPyQt5であるのは、この遅延のせいである。<br> <br> ただし、QtはPySide2を公式で採用したため、その実行可能性が確保されて、今後の人気が高まるはずである。<br> <br> <u>※注意</u><br> <u>Sideは、フィンランド語でbinderを意味するため、PySideと呼ばれている。</u><br> <br> <center> {| class="wikitable" style="background-color:#fefefe;" |- ! style="background-color:#00ffff;" | ! style="background-color:#00ffff;" | PyQt 5 ! style="background-color:#00ffff;" | PySide 2 |- | 最新安定版<br>(2021年1月現在) || 5.15 || 5.15 |- | 最初の安定版 || 2016年4月 || 2018年7月 |- | 開発者 || Riverbank Computing社 || Qt |- | ライセンス形態 || GPL<br>または<br>コマーシャル || LGPL |- | プラットフォーム || Python 3以降 || Python 3以降<br>Python 2.7(Windows x86、Linux x64、MacOS) |} </center> <br><br> == どちらを使用すべきか == PyQt5とPySide2はQt5をラッピングしているため、同じAPIが99.9%存在する。(いくつかの違いについては、後述のセクションを参照)<br> 同じソースコードをそのまま使用できることが多く、<code>import</code>文をPyQt5からPySide2に変更するだけである。<br> <br> 一方のライブラリで学習したことは、もう一方のライブラリを使用して簡単に適用できる。<br> 例えば、PyQt5のチュートリアルを使用してPySide2を使用したソフトウェアを構築することができる。<br> <br><br> == ライセンス形態 == PyQt5とPySide2のの主な違いは、ライセンス形態である。<br> <br> PyQt5は、GPLまたは商用ライセンスの下で利用可能であり、PySide2はLGPLライセンスの下で利用可能である。<br> <br> ソフトウェアをGPLの下でリリースする場合や配布されないソフトウェアを開発している場合、PyQt5のGPL要件が問題になる可能性はほとんどない。<br> ただし、ソースコードを配布せずにソフトウェアを配布する場合、Riverbank社からPyQt5の商用ライセンスを購入するか、PySide2を使用する必要がある。<br> <br> LGPLライセンスでは、PySide2にバンドルされている場合でも、開発するソフトウェアのソースコードを配布する必要はない。<br> LGPLの対象となるソースコードが利用可能になっていることを確認するだけである。(これは、変更があった場合も含まれる)<br> 通常の使用では変更はなく、既にPySide2 / Qt5の標準のソースコードでカバーされている。<br> <br> Qt5は、Qt Commercial License、GPL2.0、GPL3.0、LGPL3.0ライセンスの下で利用できる。<br> <br><br> == UIファイル == PyQt5とPySde2は、どちらもQt CreatorまたはQt Designerからエクスポートされた.uiファイルをロードすることができる。<br> ただし、わずかな差異が存在するため、以下に詳細を記載する。<br> <br> PyQt5は、UIファイルを読み込んでオブジェクトを生成するuicモジュールがある。<br> <syntaxhighlight lang="python"> # PyQt 5 import sys from PyQt5 import QtWidgets, uic app = QtWidgets.QApplication(sys.argv) window = uic.loadUi("mainwindow.ui") window.show() app.exec() </syntaxhighlight> <br> PySide2は、UIファイルを読み込むために、<code>QUILoader</code>クラスのオブジェクトを生成する必要がある。<br> これらはAPI名と引数が異なる。(<code>load</code>メソッドと<code>loadUI</code>メソッド)<br> <syntaxhighlight lang="python"> # PySide 2 import sys from PySide2 import QtCore, QtGui, QtWidgets from PySide2.QtUiTools import QUiLoader app = QtWidgets.QApplication(sys.argv) loader = QUiLoader() window = loader.load("mainwindow.ui", None) window.show() app.exec_() </syntaxhighlight> <br> PyQt5の画面オブジェクト(QMainWindow.__init__等)にUIファイルを読み込むには、<br> <code>uic.loadUI</code>メソッドを使用して、第1引数にUIファイルのパス、第2引数にself(ターゲットとなるウィジェット)を渡す。<br> <syntaxhighlight lang="python"> # PyQt 5 import sys from PyQt5 import QtCore, QtGui, QtWidgets from PyQt5 import uic class MainWindow(QtWidgets.QMainWindow): def __init__(self, *args, **kwargs): super().__init__(*args, **kwargs) uic.loadUi("mainwindow.ui", self) app = QtWidgets.QApplication(sys.argv) window = MainWindow() window.show() app.exec_() </syntaxhighlight> <br> PySide2の画面オブジェクトにUIファイルを読み込むには、<br> <code>load</code>メソッドを使用して、第1引数には、第2引数に作成しているウィジェットの親ウィジェットを渡す。<br> これにより、ウィジェットの<code>__init__</code>ブロックにカスタムコードを追加できなくなるが、別の関数を使用してこれを回避できる。<br> <syntaxhighlight lang="python"> # PySide 2 import sys from PySide2 import QtWidgets from PySide2.QtUiTools import QUiLoader def mainwindow_setup(w): w.setTitle("MainWindow Title") app = QtWidgets.QApplication(sys.argv) loader = QUiLoader() window = loader.load("mainwindow.ui", None) mainwindow_setup(window) window.show() app.exec() </syntaxhighlight> <br><br> == UIファイルをPythonファイルに変換する == PyQt5とPySide2は、.uiファイルから.pyファイルへインポート可能モジュールを生成するための同一のスクリプトを提供する。<br> <br> PyQt5の場合は、pyuic5をインストールして、以下のコマンドを実行する。<br> pyuic5 mainwindow.ui -o MainWindow.py <br> 次に、MainWindowモジュールからUI_MainWindowクラス(使用している基本クラス(QMainWIndow等)を継承したサブクラス)をインポートして、<br> <code>self.setupUI(self)</code>メソッドを使用して、UIを設定する。<br> <syntaxhighlight lang="python"> # PyQt 5 import sys from PyQt5 import QtWidgets from MainWindow import Ui_MainWindow class MainWindow(QtWidgets.QMainWindow, Ui_MainWindow): def __init__(self, *args, **kwargs): super().__init__(*args, **kwargs) self.setupUi(self) app = QtWidgets.QApplication(sys.argv) window = MainWindow() window.show() app.exec() </syntaxhighlight> <br> PySide2の場合、pyside2-uicをインストールして、以下のコマンドを実行する。<br> pyside2-uic mainwindow.ui -o MainWindow.py <br> 後の設定は、PyQt5と同様である。<br> <syntaxhighlight lang="python"> # PySide 2 import sys from PySide2 import QtWidgets from MainWindow import Ui_MainWindow class MainWindow(QtWidgets.QMainWindow, Ui_MainWindow): def __init__(self, *args, **kwargs): super().__init__(*args, **kwargs) self.setupUi(self) app = QtWidgets.QApplication(sys.argv) window = MainWindow() window.show() app.exec_() </syntaxhighlight> <br> PyQt5またはPySide2でQtDesignerを使用する方法の詳細は、[https://www.learnpyqt.com/courses/qt-creator/ Qt Creatorのチュートリアル]を参照すること。<br> <br><br> == execメソッドとexec_メソッド == execメソッドはQtで使用されており、QApplicationまたはダイアログのイベントループを開始する。<br> <br> Python 2.7では、execはキーワードだった経緯があり、変数、関数、メソッド名には使用できなかった。<br> PyQt4やPySideで実施された解決策は、この競合を回避するために、execの名前をexec_に変更することだった。<br> Python 3では、execキーワードを削除されており、名前を解放して使用できるようになった。<br> <br> PyQt5は、Python 3のみを対象としているため回避策を取り除くことができ、execメソッド名はQt自体と同じ名前となっている。<br> ただし、exec_メソッド名は、下位互換性のために維持されている。<br> <br> PySide2は、Python 3とPython 2.7の両方で使用できるため、引き続き、exec_メソッドを使用する。<br> ただし、Linux x64およびMacOSでのみ使用できる。<br> <br> <u>PyQt5とPySide2の両方をターゲットにしている場合は、exec_メソッドを使用する。</u><br> <br><br> == スロットとシグナル == PyQt5とPySide2のカスタムスロットとシグナルの定義では、わずかに差異があるシンタックスが使用される。<br> <br> PySide2は、SignalとSlotという名前でスロットとシグナルを提供している。<br> PyQt5は、pyqtSignalとpyqtSlotという名前でスロットとシグナルを提供している。<br> これらの動作は、同じである。<br> <br> 以下に示すPyQt5とPySide2の例の動作は同じである。<br> <syntaxhighlight lang="python"> # シグナル my_custom_signal = pyqtSignal() # PyQt5 my_custom_signal = Signal() # PySide2 my_other_signal = pyqtSignal(int) # PyQt5 my_other_signal = Signal(int) # PySide2 </syntaxhighlight> <br> <syntaxhighlight lang="python"> # スロット @pyqtslot def my_custom_slot(): # Do Something @Slot def my_custom_slot(): # Do Something </syntaxhighlight> <br> PyQt5とPySide2の間で一貫性を確保する場合、以下のように、PyQt5またはPySide2にimportパターンを使用して、Signalおよび@Slotを定義する。<br> <syntaxhighlight lang="python"> from PyQt5.QtCore import pyqtSignal as Signal, pyqtSlot as Slot # または from PySide2.QtCore import Signal as pyqtSignal, Slot as pyqtSlot </syntaxhighlight> <br><br> == PyQt5とPySide2の両方のサポート == PyQt5とPySide2の両方と互換性を持たせるライブラリ、ウィジェット、その他のツールを開発している場合、<br> 両方のインポートセットを追加することで簡単に実行できる。<br> <br> 以下の例は、カスタムウィジェットライブラリで使用されているアプローチであり、単一のライブラリインポートでPyQt5とPySide2をサポートしている。<br> 注意点は、sys.modulesにあることを確認するために、sysモジュールをインポートする必要がある。<br> <syntaxhighlight lang="python"> # xxx.pyファイル import sys if 'PyQt5' in sys.modules: # PyQt5 from PyQt5 import QtGui, QtWidgets, QtCore from PyQt5.QtCore import pyqtSignal as Signal, pyqtSlot as Slot else: # PySide2 from PySide2 import QtGui, QtWidgets, QtCore from PySide2.QtCore import Signal, Slot </syntaxhighlight> <br> ただし、上記の方法では、複数のPythonファイルが存在する場合、各Pythonファイルで記述するため煩雑である。<br> この解決策は、インポートロジックを独自のファイルに移動することである。<br> <br> 例えば、プロジェクトのルートにqt.pyファイルを作成して、<br> PyQt5とPySide2のいずれかからQtモジュール(QtCore、QtGui、QtWidgets等)をインポートした後、他のPythonファイルからインポートする。<br> <br> 以下に、qt.pyファイルのソースコードを記述する。<br> <u>他のPyQt5モジュールおよびPySide2モジュール(ブラウザ、マルチメディア等)を使用する場合、<code>if-else</code>ブロックの両方に追加することを忘れないこと。</u><br> <syntaxhighlight lang="python"> # qt.pyファイル(プロジェクトのルート) import sys if 'PyQt5' in sys.modules: # PyQt5 from PyQt5 import QtGui, QtWidgets, QtCore from PyQt5.QtCore import pyqtSignal as Signal, pyqtSlot as Slot else: # PySide2 from PySide2 import QtGui, QtWidgets, QtCore from PySide2.QtCore import Signal, Slot </syntaxhighlight> <br> 次に、他のPythonファイルからQt5(qt.pyファイル)をインポートする。<br> <syntaxhighlight lang="python"> # xxx.pyファイル from .qt import QtGui, QtWidgets, QtCore </syntaxhighlight> <br> その他の方法として、環境変数<code>QT_API</code>を使用して、それらを切り替える方法がある。<br> 詳細は、次のQtPyセクションを参照すること。<br> <br><br> == QtPy == Qt5以外のもの(PyQt 4やPySide 1等)をターゲットにする場合、QtPyを参照すること。<br> QtPyは、PyQt4、PyQt5、PySide1、PySide2向けの標準化されたPySide2のようなAPIが提供されている。<br> <br> QtPyを使用すると、環境変数<code>QT_API</code>を使用して、ソフトウェアから読み込むAPIを制御できる。<br> <syntaxhighlight lang="python"> import os os.environ['QT_API'] = 'pyside2' from qtpy import QtGui, QtWidgets, QtCore # imports PySide2. </syntaxhighlight> <br><br> __FORCETOC__ [[カテゴリ:Qt]]
Qtその他 - PyQt5とPySide2
に戻る。
案内
メインページ
最近の更新
おまかせ表示
MediaWiki についてのヘルプ
ツール
リンク元
関連ページの更新状況
特別ページ
ページ情報
We ask for
Donations
Collapse