PyQt5 利用ノート¶
本稿は PyQt の現時点での最新版、PyQt5 についての覚え書きである。
Note
本稿執筆時の動作環境は次のとおり。
関連リンク¶
- PyQt
PyQt 紹介ページ。リリースニュース、ダウンロード、ドキュメントへの各リンクを提供している。
- PyQt Download
自分の環境の Python のバージョンに合ったインストーラーを選択するべし。
- Qt Documentation
Qt (C++) のドキュメント。
- The PyQt Tutorial
GUI をコーディングで実装するタイプのチュートリアル。最終的にテトリス簡易版を実装する。テトリス実装例は PyQt 配布物の
examples
内にもある。
目的¶
ノートを書いておいてなんだが、今後私が PyQt を本格的に利用することはないと思う。数年前に PyQt に興味を持った理由は、所有していた私の貧弱な PC でも、Python での GUI プログラミングならば難なく実現できると考えたからだった。
現在では最近買い替えた PC の性能が良く、自室からインターネットに接続したことと、ディスク容量が格段に増えたことから、PyQt に頼る必要性がなくなった。むしろ Microsoft Visual Studio 無料版をインストールしてC# による GUI プログラミングをするほうが Windows しか使わない私としては自然な選択だ。
それでも Qt/PyQt はクラスライブラリーを見ているとためになることが多い。ドキュメントを参照するためだけにインストールしたとしても、得なのではないかと思う。
インストール¶
公式サイトが提供するバイナリーパッケージを利用してインストールする方法と、 Miniconda を利用してインストールする方法を記す。前者の方法は Python を標準インストーラーによりインストールした場合に採用し、後者の方法は Miniconda で Python 環境を管理している場合に採用することになるはずだ。
インストーラーによる方法¶
PyQt Download のページで利用環境に適した Windows 用のインストーラーをダウンロードする。本稿では
PyQt5-5.4.1-gpl-Py3.4-Qt5.4.1-x64.exe
をインストーラーとしている。ダウンロード終了後、インストーラーを起動する。
途中の選択肢はほとんどない。Full インストールを選択する程度。
普通はインストールが無事に終了する。
Miniconda による方法¶
こちらの方法は手動による設定作業を部分的に要するので自信がない。
以下、デフォルト環境に PyQt5 をインストールする手順を記すが、当然ながら PyQt5 動作確認用の環境を conda を用いて作成して、そこで構築してもよい。その場合は以下に示す各種ファイルパス等を適宜読み替えて欲しい。
大まかな手順は次の通りだ。すべてコマンドライン処理になる。
コマンド
conda install pyqt5
を実行する。環境変数
QT_QPA_PLATFORM_PLUGIN_PATH
を設定する。
実行例を示す。言い忘れたが Cygwin bash のセッションだ。
bash$ conda install -c mmcauliffe pyqt5
Fetching package metadata ...........
Solving package specifications: ..........
Package plan for installation in environment D:\Miniconda3:
The following packages will be downloaded:
package | build
---------------------------|-----------------
icu-56.1 | 0 11.1 MB mmcauliffe
qt5-5.5.1 | 0 28.8 MB mmcauliffe
pyqt5-5.5.1 | py35_0 3.9 MB mmcauliffe
------------------------------------------------------------
Total: 43.9 MB
The following NEW packages will be INSTALLED:
icu: 56.1-0 mmcauliffe
pyqt5: 5.5.1-py35_0 mmcauliffe
qt5: 5.5.1-0 mmcauliffe
Proceed ([y]/n)?
Fetching packages ...
icu-56.1-0.tar 100% |###############################| Time: X:XX:XX XXX.XX kB/s
qt5-5.5.1-0.ta 100% |###############################| Time: X:XX:XX XXX.XX kB/s
pyqt5-5.5.1-py 100% |###############################| Time: X:XX:XX XXX.XX kB/s
Extracting packages ...
[ COMPLETE ]|##################################################| 100%
Linking packages ...
INFO:progress.update:('pyqt5', 2)####################### | 66%
[ COMPLETE ]|##################################################| 100%
INFO:progress.stop:None
bash$ export QT_QPA_PLATFORM_PLUGIN_PATH='D:/Miniconda3/Library/lib/qt5/plugins/platforms/'
conda のオプション引数に
-c
を追加して、パッケージをダウンロードする channel を明示的に指定する必要があった。いずれ標準のパッケージサイトから入手可能になれば、これは不要になると思われる。最後は bash の組み込みコマンドで環境変数を set しているが、恒久的に指定してよいのであれば、セッション外で定義する。例えば Windows の環境変数を追加するようなやり方で定義する。 PyQt5 稼働テスト用環境とスイッチしながら作業する前提ならば、何か手軽に当該環境変数を set/unset するツールを自作しておくべきだろう。
Note
Miniconda の基本利用法については Miniconda 利用ノート 参照。
Note
PyQt4 との共存については調査中。特に Matplotlib のバックエンド関連での挙動に興味がある。
動作確認¶
Warning
本節の内容はインストーラーで PyQt5 をインストールした場合を前提とする。
Windows のスタートメニューから適当に辿っていくと PyQt GPL v5.4.1 for Python v3.4 (x64) のような項目ができている。
まずは Launch ボタンを押すと、デモが開始する。
を選択するとよい。PyQt で実装された様々なデモアプリのランチャーが出現する。画面左のリストから何か興味のあるものを選択して、画面下のOpenGL のデモが 2D のもの以外動かない。画面が真っ黒か、描画イベントが来ないか。
ドキュメント¶
Warning
本節の内容はインストーラーで PyQt5 をインストールした場合を前提とする。
前述のスタートメニューの オンラインヘルプ がブラウザーで読める。
を選択すると、PyQt を利用したプログラムを作成する¶
Warning
本節の内容はインストーラーで PyQt5 をインストールした場合を前提とする。
Qt Desinger は GUI を XML ファイルとして記述、保存するためのツール。
PyQt4 のときと同じように使える。
記述ファイルの拡張子は
.ui
となる。Qt Desinger 付属のバッチファイル
pyuic5.bat
は ui ファイルから py コードを生成するものだ。Python コードから ui ファイルに定義されている GUI を利用することができる。方法は二系統あり、ui ファイルを直接ロードするものと、バッチで生成した py モジュールのクラスをインスタンス化する方法にわかれる。
まずは Qt Designer の利用方法を習得する。目標は次の方法を習得することとしよう。
ui ファイルを保存する方法。
ui ファイルから py ファイルを生成する方法。
ui ファイルで定義した Widget を自作プログラムが利用する方法。
Qt Desinger¶
前述スタートメニューの
を選択する。Designer は GUI を設計するためのツール。設計内容は拡張子 ui のファイルに
または する。新規 widget を作成すると、真っ白なウィンドウを画面中央に出す。あとは一般的な RAD ツールと同じように、子 widget をゴテゴテ盛っていく。
各 widget 要素の変数名等のプロパティを変更するには、画面右のオブジェクトインスペクタやプロパティエディタを利用する。
のショートカットキーは Ctrl + R のようだ。
メニュー項目は使いものにならない。 PyQt4 からこの不具合が解消されていないとは?手動で ui ファイルから py ファイルを生成するしかない。
PyQt5 インストールフォルダーにある
pyuic5.bat
をパスの通ったフォルダーにコピーして、コンソールから同バッチを実行する。コマンドライン引数は Designer で保存した ui ファイル一丁。bash$ pyuic5.bat myform.ui > ui_myform.py
一番親の widget にレイアウトを設定するにはコツが要る。ある程度子 widget を親 widget に搭載したら、親で右クリックメニュー表示。
のサブメニューに色々あるので、所望の配置スタイルを選択する。シグナル/スロットの編集はかなり直感的に設定できる。
F4 キーでシグナル/スロット編集モードに移行。connect 関係を定義したい widget 間をドラッグアンドドロップ。ドロップ直後にわかりやすい入力フォームが現れるので、そこで指示。
なお F3 キーで GUI 編集モードに移行。
以降の説明では、各ファイル名を次のように決めたものとする。
ファイルの名前 |
ファイルの意味 |
---|---|
|
Qt Designer での GUI 設計内容を保存した XML ファイル |
|
上記 ui ファイルを |
|
設計した GUI を利用する Python スクリプトファイル |
ui ファイルから生成した py ファイルの利用法¶
ファイル ui_myform.py
をそのまま実行しても、 Qt Designer で設計した
Widget が出てくるわけではない。別のコード(ここでは myapp.py
としている)から import して利用する。
色々な流儀があるので、以下に記す。
myform.Ui_Form
インスタンスを作成する方法¶
#!/usr/bin/env pythonw
"""myapp1.pyw: Create an instance of Ui_Form.
"""
# pylint: disable=no-name-in-module
import sys
from PyQt5.QtWidgets import (QApplication, QWidget)
# pyuic5.bat myform.ui > ui_myform.py
from ui_myform import Ui_Form
def main():
"""Main loop."""
app = QApplication(sys.argv)
window = QWidget()
ui = Ui_Form()
ui.setupUi(window)
window.show()
sys.exit(app.exec_())
if __name__ == '__main__':
main()
QWidget
のサブクラスで UI_Form.setupUI
を利用する方法¶
class Form(QWidget):
"""The second example shows the single inheritance approach where we
sub-class QWidget and set up the user interface in the __init__() method.
"""
def __init__(self):
super(Form, self).__init__()
# Set up the user interface from Designer.
self.ui = Ui_Form()
self.ui.setupUi(self)
# Connect up the buttons.
self.ui.pushButton.clicked.connect(self.accept)
def accept(self):
"""NOP"""
pass
def main():
"""Main loop."""
app = QApplication(sys.argv)
window = Form()
window.show()
sys.exit(app.exec_())
if __name__ == '__main__':
main()
インポートは先程と同様。
QWidget
と Ui_Form
のサブクラスで setupUI
を利用する方法¶
def __init__(self):
super(Form, self).__init__()
self.setupUi(self)
self.pushButton.clicked.connect(self.accept)
インポートと main
は先程と同様。
ui ファイルから直接 Widget
をロードする方法¶
関数 uic.loadUI
を利用する。
#!/usr/bin/env pythonw
"""myapp4.pyw: Directly load Widget from myform.ui.
"""
# pylint: disable=no-name-in-module
import sys
from os.path import (dirname, join)
from PyQt5 import uic
from PyQt5.QtWidgets import QApplication
def main():
"""Directly load Widget from myform.ui."""
app = QApplication(sys.argv)
window = uic.loadUi(join(dirname(__file__), 'myform.ui'))
window.show()
sys.exit(app.exec_())
if __name__ == '__main__':
main()
サブクラスに差し替える方法¶
例えば QTextBrowser
を自分でこれから作成する予定のサブクラス
QMyTextBrowser
に差し替えたい場合は次の手順をとる。
デザイナー画面の
QTextBrowser
アイテム上で右クリックメニューを表示し、 を選択する。入力フォームが出現する。下部にある 格上げされたクラス名 に
QMyTextBrowser
と入力する。追加 を押す。
格上げ を押す。
デザイナーで ui ファイルを保存する。
pyuic5.bat
で ui ファイルから py ファイルを生成すると、ファイルの下の方にimport qmytextbrowser
という行が入っているハズ。qmytextbrowser.py
ファイルを作成し、自分でクラスを実装すればよい。from PyQt5 import QtWidgets class QMyTextBrowser(QtWidgets.QTextBrowser): ...