
Python+Qtアプリ開発日記#6
前回からの続き
前回は、開発環境を作ってGitHubとかにリポジトリ公開などしました。
今回は、簡単なウインドウをデザインして表示するまでです。
実行時作成されるファイル
何も設定しなければPythonスクリプト実行時に"__pycache__"というフォルダができる。これは実行時にPythonによってpyファイルからバイトコードに変換されたものが入るいわゆるキャッシュ。基本的には不要になるものなので、作られないようにします。
.envを作る
git対象外にしてもいいが手っ取り早くワークスペースに".env"というファイルを作って、中身は以下にように"PYTHONDONTWRITEBYTECODE"を有効にする。ここの"1"は意味はなく"0"以外ならOK。
これでデバック時にキャッシュは作られなくなります。
※既に"__pycache__"ができていれば削除します。
PYTHONDONTWRITEBYTECODE=1
このファイルを配置(作成)したた結果は、こんな感じ。

Qt(Pyside6)の導入
ここからは、Qtを導入していく。導入すると言ってもpipを使ってインストールするだけです。ターミナルでpipが動作することを"pip -V"とかで確認します。

正しく動くので、pip install pyside6でインストールします。
※QtのPythonバインディングは、Pyside以外にもPyQtがあります。細かな違いはあるけどできることは一緒ですですが、Qt公式が出しているPysideを今回は使います。

インストールができたら、正しく入ったかをpip listなどで確認。

pipが古いよ。新しいのあるよ。といってくるのでついでに新しくします。

念の為、".VENV"の中も確認します。

あとは、Pythonコードでゴリゴリコーディングしてユーザーインタフェース画面を作ってもよし、pyside6付属のQt Designerを使ってもよしになります。作り込んで行くと結局はコードで色々することになりますが、まず見た目を検討するのにはQt Designerを使うのがいいと思います。
Qt Designerを使う準備
何も考えないでQt Designerを使ってもいいですが、PythonコードとQt Designerが作るファイルを一緒のところに置くのは管理できなるなるのでQt Designerでデザインするときの場所を作ります。場所といってもディレクトリを新しく作るだけです。ワークスペースに"ui_design"というディレクトリを作成し、その配下にバッチファイルとuiファイルを格納する"ui"というディレクトリを作りました。

作ったバッチファイルの簡単な説明をすると
"ui_edit.bat"は、.VENVにあるQt Designerを起動するだけのバッチファイルです。
"cv.bat"は、Qt Designerで作ったuiファイルをPythonコードに変換するツールを呼び出すバッチファイルです。内容は少し長いですが、起動するとカレントディレクトリ以下にあるファイル拡張子"ui"のファイルをpyside6付属のPythonコードに変換するツールで一括変換するバッチファイルです。
Qt Designer起動
ターミナルで、作成した"ui_design"をカレントディレクトリにして、"ui_edit.bat"を実行します。
正しく実行できれば、Qt Designerが起動します。

今回は、メインウインドウを作りたいので、メインウインドウの作成を選択します。

あとはここに色々配置していきますが、今回はこのまま名前をつけて保存します。
main_windowと名前をつけて保存しました。保存先は先に用意した"ui"というフォルダに一旦、保存します。
今回は、作成したuiファイルをそのまま表示するので、できたuiファイルを
Pythonコードと同じディレクトリ(正確には実行時のカレントディレクトリ)にコピーしておきます。

また、uiファイルを表示するコードを準備します。
上記の図では、"gui"というフォルダを作成して、3つのPythonコードファイルを既に作った状態です。
"__init__.py" guiをパッケージとするためのファイル。
中身は空ではなく、"launch.py"で定義したモジュールをインポートできるように記述しています。
from .launch import app_run
__all__ = [
"app_run",
]
"launch.py" やっていることは大したことはしていませんが、ここで定義したモジュール"app_run"で、QApplicationオブジェクトのインスタンス作成とメインウインドウのクラス生成です。
また、起動時の引数やアプリケーションの戻り値を返すために、sysをインポートしています。
※メインウインドウのクラスインスタンスを"_"無名関数にしていますが、これは暫定処理です。
import sys
from PySide6.QtWidgets import QApplication
from .gmain import MWindow
def app_run() -> int:
"""
アプリケーションを実行する関数。
この関数はQApplicationを初期化し、メインウィンドウを作成して表示します。
Args:
app_config (AppConfig): アプリケーションの設定を含むAppConfigオブジェクト。
Returns:
int: アプリケーションの終了コード。
"""
app = QApplication(sys.argv)
_ = MWindow()
return app.exec()
"gmain.py" やっていることは、大したことはしていません。
"__init__"メソッドで、uiファイルをそのまま読み込める、
QtUiTools.QUiLoaderを生成して、"load"メソッドで先にカレントディレクトリにコピーした"main_window.ui"を読み込んでします。
読み込み後にそのまま、"show"メソッドで表示しています。
import os
from PySide6 import QtUiTools
class MWindow:
def __init__(self):
aUILoader = QtUiTools.QUiLoader()
ui_file_path = os.path.join(os.getcwd(), "main_window.ui")
self.main_window = aUILoader.load(ui_file_path)
self.main_window.show()
"main.py"を修正する。
"gui"パッケージから"app_run"をインポートします。

mainモジュールのreturn 0を"app_run()"を呼び出す様にします。

デバック実行すると、以下のようなウインドウが表示されれば正しく動作しています。正しく表示されない!あるいは例外が出た!場合は、実行時のカレントディレクトリなどが間違っていないか?を確認します。

次回は、uiファイルからPythonコードにしてそれを実行することを行います。
いいなと思ったら応援しよう!
