見出し画像

PySide MainWindowのラッパークラス

PySideQMainWindowでツールを作るさい、同じ記述を何回もするのがめんどうなので、共通で記述する部分をラッパークラスを作ってまとめてみる。

ライブラリ化

import os
import json
from logging import config, getLogger
from PySide2.QtCore import QFile
from PySide2.QtWidgets import (
	QMainWindow,
	QStatusBar
)
from PySide2.QtUiTools import QUiLoader

class EbMainWindow(QMainWindow):
	def __init__(self, parent=None):
		QMainWindow.__init__(self, parent)

	def setupLogger(self, dir, config_file, logger_name):
		config_path = os.path.join(dir, config_file)
		with open(config_path, 'r') as f:
			log_conf = json.load(f)
			log_conf['handlers']['fileHandler']['filename'] = os.path.join(dir, log_conf['handlers']['fileHandler']['filename'])
			config.dictConfig(log_conf)
		self.logger = getLogger(logger_name)
		self.logger.debug(config_path)

	def loadUI(self, dir, file_name):
		# Load ui file
		loader = QUiLoader()
		ui_file_path = os.path.join(dir, file_name)
		ui_file = QFile(ui_file_path)
		ui_file.open(QFile.ReadOnly)
		self.ui = loader.load(ui_file, self)
		ui_file.close()

	def initUI(self, status_bar):
		# Set Window Title
		title = self.ui.windowTitle()
		self.setWindowTitle(title)
		# Set Window Size
		w = self.ui.size().width()
		h = self.ui.size().height()
		self.resize(w, h)
		if status_bar == True:
			self.__enableStatusBar()

	def __enableStatusBar(self):
		# Set Status Bar
		# Instance Variable
		self.statusbar = self.ui.findChild(QStatusBar, 'statusbar')
		self.setStatusBar(self.statusbar)

	def showMessage(self, message):
		self.statusbar.showMessage(message)

共通に出来そうな部分は、ロガーの設定、UIファイルの読み込み、MainWindowで共通なタイトル、サイズ、ステータスバー。
とりあえず、今回思いつくのはこの辺だったので、他に共通化できそうならバージョンアップしていきたい。
ロガーについてはWebにいろいろあるので、ここでは説明しない。

■追加

	# menuのparamを追加
    def initUI(self, menu_bar:bool, status_bar:bool):
        # 上記に以下を追加
		if menu_bar == True:
			self.__enableMenuBar()

	def __enableMenuBar(self):
		menubar = self.ui.findChild(QMenuBar, 'menubar')
		self.setMenuBar(menubar)

	def addMenuAction(self, menu_name:str, action:QAction):
		menu = self.menuBar().findChild(QMenu, menu_name)
		menu.addAction(action)
		self.menuBar().addMenu(menu)

前回のラッパーに、メニューの項目を追加。
継承側では以下の記述でメニューを登録できている。
※階層メニューは検証が必要

		# Set MenuBar
		ui_action = self.ui.findChild(QAction, 'action_manual')
		manual_action = QAction(ui_action.text(), self)
		manual_action.setObjectName(ui_action.objectName())
		manual_action.triggered.connect(self.showManual)
		self.addMenuAction('menu_help', manual_action)

フォルダ階層

フォルダ階層

とりあえずは図のような感じ。
libフォルダの下に、パッケージとしてeastbosk.uiのフォルダがある。
logフォルダはロガーで出力するログファイルの場所。
uiフォルダはQt Designerで作成したuiファイルの場所。
pysideフォルダ直下にpyファイルがあるので、それはsrcフォルダを作った方がいいかもと考えてる。
後は、設定ファイル類はconfフォルダとか・・まだ改良は必要。

テンプレート

Qt Designerで図のようなUIを作成。

サンプルUI
import sys
import os
import qtmax
from PySide2 import *
from PySide2.QtWidgets import *

eb_path = os.path.join(os.path.dirname(os.path.realpath(__file__)), '.\\lib')
sys.path.append(eb_path)

from eastbosk.ui.EbPySideLibs import EbMainWindow

class EbWindow(EbMainWindow):
	def __init__(self):
		super().__init__(qtmax.GetQMaxMainWindow())
		# 実行ディレクトリ取得
		self.cur_dir = os.path.dirname(os.path.realpath(__file__))
		# ロガーの設定
		self.setupLogger(self.cur_dir, "log_config.json", "debugLogger")
		# PySideのUIファイルを読み込み
		self.loadUI(self.cur_dir, ".\\ui\\ui_EbMainWindow.ui")
		# UIの初期設定、TrueでStatusBarが有効になる。
		self.initUI(True)
		# 個別UIの設定
		self.__setupUI()
	
    # ここのプライベート関数で、それぞれ個別のUI設定をする。
	def __setupUI(self):
		widget = self.ui.centralWidget()
		h_lo = self.ui.findChild(QHBoxLayout, 'h_lo')
		ok_btn = self.ui.findChild(QPushButton, 'ok_btn')
		ok_btn.clicked.connect(self.okClicked)
		h_lo.addWidget(ok_btn)
		widget.setLayout(h_lo)
		self.setCentralWidget(widget)

		self.logger.debug("Setup UI")

	def okClicked(self):
		self.showMessage("OK")

def main():
	window = EbWindow()
	window.show()

if __name__ == '__main__':
	main()
起動画面

このコードがテンプレートになるので、新たにツールを作成する場合は、このコードをコピーして使用する感じになる。
相対パス関連は適宜変更する。

QDialogも後で作るかも。

とりあえず、今後のツールはこれで作成していくと思う・・

この記事が気に入ったらサポートをしてみませんか?