Qt for Pythonで手軽にGUIアプリを作る (導入編)
はじめに
少し前になりますが、 Qt Blog の記事でPyPIからQt for Pythonを利用できるようになったとアナウンスがありました。
今回はQt for Pythonを使ったGUIアプリケーションを試してみます。
検証環境
- Python: 3.7.0
- Pipenv: 2018.05.18
- PySide2: 5.11.0 (Qt for python)
Qtって何?
Qtはクロスプラットフォーム開発のためのフレームワークです。今回はGUIの機能を利用しますが、ネットワークやマルチメディアなど数多くのライブラリが用意されています。 対応しているプラットフォームも多く、デスクトップ・スマートフォン・組み込み機器と多くの環境で利用できるようです。
また、シグナル・スロットと呼ばれる仕組みが用意されていて、簡単に Observer を実装できるようになっています。
今回はシグナル・スロットを使って、ボタンを押したらダイアログを表示するだけの簡単なGUIアプリケーションを作成してみます。
環境構築
Pipenv を使ってQt for Pythonの環境を構築します。
まず、Pipenvの環境を構築します。今回はCPython3.7.0を使います。
$ mkdir qt-for-python $ cd qt-for-python $ pipenv install --python 3.7.0 Creating a virtualenv for this project… Using /Users/yoshihitoh/.pyenv/versions/3.7.0/bin/python3.7m (3.7.0) to create virtualenv… ⠋Running virtualenv with interpreter /Users/yoshihitoh/.pyenv/versions/3.7.0/bin/python3.7m Using base prefix '/Users/yoshihitoh/.pyenv/versions/3.7.0' /Users/yoshihitoh/.pyenv/versions/3.6.5/lib/python3.6/site-packages/virtualenv.py:1041: DeprecationWarning: the imp module is deprecated in favour of importlib; see the module's documentation for alternative uses import imp New python executable in /Users/yoshihitoh/.local/share/virtualenvs/qt-for-python-T_faoBtg/bin/python3.7m Also creating executable in /Users/yoshihitoh/.local/share/virtualenvs/qt-for-python-T_faoBtg/bin/python Installing setuptools, pip, wheel...done. Virtualenv location: /Users/yoshihitoh/.local/share/virtualenvs/qt-for-python-T_faoBtg Creating a Pipfile for this project… Pipfile.lock not found, creating… Locking [dev-packages] dependencies… Locking [packages] depend encies… Updated Pipfile.lock (a65489)! Installing dependencies from Pipfile.lock (a65489)… ▉▉▉▉▉▉▉▉▉▉▉▉▉▉▉▉▉▉▉▉▉▉▉▉▉▉▉▉▉▉▉▉ 0/0 — 00:00:00 To activate this project's virtualenv, run the following:
上記の手順でPipenvのシェルに切り替わると思いますが、もし変わらない場合は明示的に切り替えましょう。
$ pipenv shell
次に、Qt for Pythonをインストールします。冒頭に書いたとおりPyPIからインストールできるようになったので、コマンド1発でインストールできます。
$ pipenv install pyside2 Installing pyside2… Collecting pyside2 Using cached https://files.pythonhosted.org/packages/cf/6b/fd9f375bcbe76df0e85729956c3ce3a299b38efbd9d61c6bd58fe5c9bf9e/PySide2-5.11.0-5.11.0-cp35.cp36-abi3-macosx_10_11_intel.whl Installing collected packages: pyside2 Successfully installed pyside2-5.11.0 Adding pyside2 to Pipfile's [packages]… Pipfile.lock (7fafad) out of date, updating to (d69f89)… Locking [dev-packages] dependencies… Locking [packages] dependencies… Updated Pipfile.lock (d69f89)! Installing dependencies from Pipfile.lock (d69f89)… ▉▉▉▉▉▉▉▉▉▉▉▉▉▉▉▉▉▉▉▉▉▉▉▉▉▉▉▉▉▉▉▉ 2/2 — 00:00:00
簡単にインストールできましたね!せっかくなのでインストールした内容を確認してみましょう。
$ cd "$VIRTUAL_ENV/lib/python3.7/site-packages/PySide2" $ ls -la total 212488 drwxr-xr-x 6 yoshihitoh staff 204B 7 27 15:34 Qt -rwxr-xr-x 1 yoshihitoh staff 333K 7 27 15:34 Qt3DAnimation.abi3.so -rwxr-xr-x 1 yoshihitoh staff 400K 7 27 15:34 Qt3DCore.abi3.so -rwxr-xr-x 1 yoshihitoh staff 776K 7 27 15:34 Qt3DExtras.abi3.so -rwxr-xr-x 1 yoshihitoh staff 411K 7 27 15:34 Qt3DInput.abi3.so -rwxr-xr-x 1 yoshihitoh staff 75K 7 27 15:34 Qt3DLogic.abi3.so -rwxr-xr-x 1 yoshihitoh staff 1.8M 7 27 15:34 Qt3DRender.abi3.so -rwxr-xr-x 1 yoshihitoh staff 1.4M 7 27 15:34 QtCharts.abi3.so -rwxr-xr-x 1 yoshihitoh staff 42K 7 27 15:34 QtConcurrent.abi3.so -rwxr-xr-x 1 yoshihitoh staff 4.3M 7 27 15:34 QtCore.abi3.so -rwxr-xr-x 1 yoshihitoh staff 1.1M 7 27 15:34 QtDataVisualization.abi3.so -rwxr-xr-x 1 yoshihitoh staff 4.9M 7 27 15:34 QtGui.abi3.so -rwxr-xr-x 1 yoshihitoh staff 522K 7 27 15:34 QtHelp.abi3.so -rwxr-xr-x 1 yoshihitoh staff 821K 7 27 15:34 QtLocation.abi3.so -rwxr-xr-x 1 yoshihitoh staff 116K 7 27 15:34 QtMacExtras.abi3.so -rwxr-xr-x 1 yoshihitoh staff 1.9M 7 27 15:34 QtMultimedia.abi3.so -rwxr-xr-x 1 yoshihitoh staff 258K 7 27 15:34 QtMultimediaWidgets.abi3.so -rwxr-xr-x 1 yoshihitoh staff 1.3M 7 27 15:34 QtNetwork.abi3.so -rwxr-xr-x 1 yoshihitoh staff 473K 7 27 15:34 QtOpenGL.abi3.so -rwxr-xr-x 1 yoshihitoh staff 416K 7 27 15:34 QtPositioning.abi3.so -rwxr-xr-x 1 yoshihitoh staff 469K 7 27 15:34 QtPrintSupport.abi3.so -rwxr-xr-x 1 yoshihitoh staff 527K 7 27 15:34 QtQml.abi3.so -rwxr-xr-x 1 yoshihitoh staff 867K 7 27 15:34 QtQuick.abi3.so -rwxr-xr-x 1 yoshihitoh staff 133K 7 27 15:34 QtQuickWidgets.abi3.so -rwxr-xr-x 1 yoshihitoh staff 253K 7 27 15:34 QtScxml.abi3.so -rwxr-xr-x 1 yoshihitoh staff 830K 7 27 15:34 QtSensors.abi3.so -rwxr-xr-x 1 yoshihitoh staff 644K 7 27 15:34 QtSql.abi3.so -rwxr-xr-x 1 yoshihitoh staff 212K 7 27 15:34 QtSvg.abi3.so -rwxr-xr-x 1 yoshihitoh staff 157K 7 27 15:34 QtTest.abi3.so -rwxr-xr-x 1 yoshihitoh staff 132K 7 27 15:34 QtTextToSpeech.abi3.so -rwxr-xr-x 1 yoshihitoh staff 645K 7 27 15:34 QtUiTools.abi3.so -rwxr-xr-x 1 yoshihitoh staff 80K 7 27 15:34 QtWebChannel.abi3.so -rwxr-xr-x 1 yoshihitoh staff 41K 7 27 15:34 QtWebEngine.abi3.so -rwxr-xr-x 1 yoshihitoh staff 145K 7 27 15:34 QtWebEngineCore.abi3.so -rwxr-xr-x 1 yoshihitoh staff 416K 7 27 15:34 QtWebEngineWidgets.abi3.so -rwxr-xr-x 1 yoshihitoh staff 143K 7 27 15:34 QtWebSockets.abi3.so -rwxr-xr-x 1 yoshihitoh staff 9.6M 7 27 15:34 QtWidgets.abi3.so -rwxr-xr-x 1 yoshihitoh staff 560K 7 27 15:34 QtXml.abi3.so -rwxr-xr-x 1 yoshihitoh staff 296K 7 27 15:34 QtXmlPatterns.abi3.so -rw-r--r-- 1 yoshihitoh staff 1.9K 7 27 15:34 __init__.py drwxr-xr-x 5 yoshihitoh staff 170B 7 27 15:34 __pycache__ -rw-r--r-- 1 yoshihitoh staff 707B 7 27 15:34 _config.py -rw-r--r-- 1 yoshihitoh staff 2.4K 7 27 15:34 _git_pyside_version.py drwxr-xr-x 24 yoshihitoh staff 816B 7 27 15:34 examples drwxr-xr-x 4 yoshihitoh staff 136B 7 27 15:34 include -rwxr-xr-x 1 yoshihitoh staff 64M 7 27 15:34 libclang.dylib -rwxr-xr-x 1 yoshihitoh staff 208K 7 27 15:34 libpyside2.abi3.5.11.dylib -rwxr-xr-x 1 yoshihitoh staff 199K 7 27 15:34 libshiboken2.abi3.5.11.dylib -rwxr-xr-x 1 yoshihitoh staff 212K 7 27 15:34 pyside2-lupdate -rwxr-xr-x 1 yoshihitoh staff 72K 7 27 15:34 pyside2-rcc drwxr-xr-x 5 yoshihitoh staff 170B 7 27 15:34 scripts -rwxr-xr-x 1 yoshihitoh staff 2.0M 7 27 15:34 shiboken2 -rwxr-xr-x 1 yoshihitoh staff 21K 7 27 15:34 shiboken2.abi3.so drwxr-xr-x 5 yoshihitoh staff 170B 7 27 15:34 support drwxr-xr-x 55 yoshihitoh staff 1.8K 7 27 15:34 typesystems
Qt*.so
や libclang.dylib
といった依存ライブラリも同梱されているので、別途インストールする必要は無いようです。
試す
プログラム
同梱の examples/
以下のファイルを参考に実装してみましょう。
import sys from PySide2 import QtWidgets def show_message(): messagebox = QtWidgets.QMessageBox(QtWidgets.QMessageBox.Information, 'Title - Hello', 'Hello, Qt for Python!', QtWidgets.QMessageBox.Close ) messagebox.exec_() def main(): # アプリケーション作成、Qt初期化のために最初にインスタンス化すること app = QtWidgets.QApplication(sys.argv) # ボタン作成 button = QtWidgets.QPushButton('click me!') button.resize(100, 40) button.show() # ボタンクリック時のシグナルに、メッセージ表示のスロット(関数)を結びつける button.clicked.connect(show_message) # アプリケーションを起動する sys.exit(app.exec_()) if __name__ == '__main__': main()
QApplication
のインスタンス生成前にボタンやメッセージボックスを作成すると、 QWidget: Must construct a QApplication before a QWidget
というエラーが発生するようです。
実行結果
早速実行してみましょう
$ python main.py
GUIが起動しましたね!ボタンをクリックしてみましょう
メッセージボックスも表示されました!シグナル/スロットの接続も問題なさそうですね。
おわりに
今回はQt for Pythonを使って簡単にGUIアプリケーションを組めることを確認できました。
Qtの特徴であるシグナル・スロットはとても便利な機構です。
今回は QPushButton
に定義されているシグナルを使ってみましたが、次回は独自のシグナルを実装する例を試してみたいと思います。