BoxLayoutをQtWidgets.QWidgetの拡張にしてみる
pyside2(pyqt5)がわかりずらいのは、QtWidgets.QHBoxLayoutとかQtWidgets.QVBoxLayoutがQtWidgets.QWidgetの拡張じゃないせいだと理解した。それで、BoxLayoutをQtWidgets.QWidgetに取り込んでみた。それと、layoutは入れ子構造なのに、pythonがインデントに厳格なせいで、更に分かりずらくなっている。かなり強引だが、スクリプトからレイアウトが、イメージできるような書き方を考えてみた。
import sys
from PySide2 import QtCore,QtWidgets
class HLayoutWidget(QtWidgets.QWidget):
def __init__(self):
super().__init__()
self.layout = QtWidgets.QHBoxLayout()
self.setLayout(self.layout)
def addWidget(self,w):
self.layout.addWidget(w)
class VLayoutWidget(QtWidgets.QWidget):
def __init__(self):
super().__init__()
self.layout = QtWidgets.QVBoxLayout()
self.setLayout(self.layout)
def addWidget(self,w):
self.layout.addWidget(w)
class Window(HLayoutWidget):
def __init__(self):
super().__init__()
self.resize(500, 500)
self.setWindowTitle("layout demo")
leftLayout = VLayoutWidget(); self.layout.addWidget(leftLayout)
leftButton1 = QtWidgets.QPushButton(); leftLayout.addWidget(leftButton1)
leftButton2 = QtWidgets.QPushButton(); leftLayout.addWidget(leftButton2)
leftButton3 = QtWidgets.QPushButton(); leftLayout.addWidget(leftButton3)
rightLayout = VLayoutWidget(); self.layout.addWidget(rightLayout)
self.rightButton1 = QtWidgets.QPushButton("Button1"); rightLayout.addWidget(self.rightButton1)
self.rightButton2 = QtWidgets.QPushButton("Button2"); rightLayout.addWidget(self.rightButton2)
leftLayout.sizeHint = lambda: QtCore.QSize(450,240)
leftLayout.setSizePolicy(QtWidgets.QSizePolicy.Maximum, QtWidgets.QSizePolicy.Expanding)
rightLayout.layout.setContentsMargins(0, 0, 0, 0)
leftButton1.setIcon(self.style().standardIcon(QtWidgets.QStyle.SP_TitleBarMenuButton))
leftButton2.setIcon(self.style().standardIcon(QtWidgets.QStyle.SP_MessageBoxInformation))
leftButton3.setIcon(self.style().standardIcon(QtWidgets.QStyle.SP_MessageBoxQuestion))
self.rightButton1.clicked.connect(self.hoge1)
self.rightButton2.clicked.connect(self.hoge2)
def hoge1(self):
self.rightButton1.setText("Button click")
def hoge2(self):
self.rightButton2.setText("Button click")
if __name__ == '__main__':
app = QtWidgets.QApplication(sys.argv)
window = Window()
window.show()
sys.exit(app.exec_())
シンプルな入れ子構造がいい
QtWidgets.QHBoxLayoutは、addWidget()で子を持つことはできる。だけど、QtWidgets.QWidgetのように実体をもってないので、サイズの変更ができない。サイズを変更するにはQtWidgets.QWidgetにsetLayout()を使ってQtWidgets.QWidgetにセットしなければならない。セットしなくてもレイアウトはできる。この辺りが、面倒なところである。いっそのことQtWidgets.QWidgetにaddWidget()を組み込めば書き方がシンプルになると思い試してみた。
レイアウトは入れ子構造なのに、pythonがインデントに厳格なせいで、更に分かりずらく部分については、pythonで ; を使っての1行で書くやり方で親子関係も、わかりやすくなった。
レイアウト部分、Widgetの細かい調整、シグナル、スロットと分けて書けば、Qtデザイナーを使わずに、直感的に書ける。かなりシンプルになりました。