↑ページトップへ

Qt for Python レイアウト方法

更新:2019/3/14
PySide2 5.12.1Python 3.7.2

Qt for Pythonではレイアウトを使ってウィジェットを配置します。ウィジェットの位置関係、サイズは使用しているレイアウトに従って決まります。

レイアウトの種類

レイアウトには以下の物があります。

  • QHBoxLayout - 水平方向にウィジェットを並べる

    # -*- coding: utf-8 -*-
    
    from PySide2.QtWidgets import *
    
    class MyLayoutDialog(QDialog):
    	def __init__(self, parent=None):
    		super(MyLayoutDialog, self).__init__(parent)
    		self.setWindowTitle("My Layout Dialog")
    		
    		# 並べるボタンを作成
    		buttonA = QPushButton("Button A")
    		buttonB = QPushButton("Button B")
    		buttonC = QPushButton("Button C")
    		
    		# 水平方向にボタンを並べる
    		layout = QHBoxLayout()
    		layout.addWidget(buttonA)
    		layout.addWidget(buttonB)
    		layout.addWidget(buttonC)
    		self.setLayout(layout)
    
    if __name__ == '__main__':
    	import sys
    	app = QApplication(sys.argv)
    	ui = MyLayoutDialog()
    	ui.show()
    	app.exec_()
    
    HBoxLayout実行結果
  • QVBoxLayout - 垂直方向にウィジェットを並べる

    # -*- coding: utf-8 -*-
     
    from PySide2.QtWidgets import *
    
    class MyLayoutDialog(QDialog):
    	def __init__(self, parent=None):
    		super(MyLayoutDialog, self).__init__(parent)
    		self.setWindowTitle("My Layout Dialog")
    		
    		# 並べるボタンを作成
    		buttonA = QPushButton("Button A")
    		buttonB = QPushButton("Button B")
    		buttonC = QPushButton("Button C")
    		
    		# 垂直方向にボタンを並べる
    		layout = QVBoxLayout()
    		layout.addWidget(buttonA)
    		layout.addWidget(buttonB)
    		layout.addWidget(buttonC)
    		self.setLayout(layout)
    
    if __name__ == '__main__':
    	import sys
    	app = QApplication(sys.argv)
    	ui = MyLayoutDialog()
    	ui.show()
    	app.exec_()
    
    VBoxLayout実行結果
  • QGridLayout - 格子状にウィジェットを並べる

    # -*- coding: utf-8 -*-
     
    from PySide2.QtWidgets import *
    
    class MyLayoutDialog(QDialog):
    	def __init__(self, parent=None):
    		super(MyLayoutDialog, self).__init__(parent)
    		self.setWindowTitle("My Layout Dialog")
    		
    		# 並べるボタンを作成
    		buttonA = QPushButton("Button A")
    		buttonB = QPushButton("Button B")
    		buttonC = QPushButton("Button C")
    		
    		# 格子状にボタンを並べる
    		layout = QGridLayout()
    		layout.addWidget(buttonA, 0, 0) # 0行 0列 に追加
    		layout.addWidget(buttonB, 1, 0) # 1行 0列 に追加
    		layout.addWidget(buttonC, 1, 1) # 1行 1列 に追加
    		self.setLayout(layout)
    
    if __name__ == '__main__':
    	import sys
    	app = QApplication(sys.argv)
    	ui = MyLayoutDialog()
    	ui.show()
    	app.exec_()
    
    QGridLayout実行結果
  • QFormLayout - 入力フォームのためのレイアウト

    # -*- coding: utf-8 -*-
    
    from PySide2.QtWidgets import *
    
    class MyLayoutDialog(QDialog):
    	def __init__(self, parent=None):
    		super(MyLayoutDialog, self).__init__(parent)
    		self.setWindowTitle("My Layout Dialog")
    		
    		# 並べるウィジェットを作成
    		labelA = QLabel("Label A")
    		labelB = QLabel("Label B")
    		labelC = QLabel("Label C")
    		buttonA = QPushButton("Button A")
    		buttonB = QPushButton("Button B")
    		buttonC = QPushButton("Button C")
    		
    		# 「ラベル - ボタン」を1行として縦方向に並べる
    		layout = QFormLayout()
    		layout.addRow(labelA, buttonA)
    		layout.addRow(labelB, buttonB)
    		layout.addRow(labelC, buttonC)
    		self.setLayout(layout)
    
    if __name__ == '__main__':
    	import sys
    	app = QApplication(sys.argv)
    	ui = MyLayoutDialog()
    	ui.show()
    	app.exec_() 
    
    FormLayout実行結果
  • QStackedLayout - ウィジェットを積み重ねてレイアウト

    # -*- coding: utf-8 -*-
    
    from PySide2.QtWidgets import *
    
    class MyLayoutDialog(QDialog):
    	def __init__(self, parent=None):
    		super(MyLayoutDialog, self).__init__(parent)
    		self.setWindowTitle("My Layout Dialog")
    		
    		# ページとして並べるウィジェットを作成
    		labelA = QLabel("Label A")
    		labelB = QLabel("Label B")
    		labelC = QLabel("Label C")
    		
    		# ページ切り替え用コンボボックス
    		combo = QComboBox()
    		combo.addItem('Page A')
    		combo.addItem('Page B')
    		combo.addItem('Page C')
    
    		# ページを追加していく
    		layout = QStackedLayout()
    		layout.addWidget(labelA)
    		layout.addWidget(labelB)
    		layout.addWidget(labelC)
    
    		# コンボボックスの切り替えでページを切り替えるようシグナルとスロットを接続
    		combo.currentIndexChanged.connect(layout.setCurrentIndex)
    
    		# ページ切り替え用コンボボックスとスタックレイアウトを垂直方向に並べる
    		vLayout = QVBoxLayout()
    		vLayout.addWidget(combo)
    		vLayout.addLayout(layout)
    		self.setLayout(vLayout)
    
    if __name__ == '__main__':
    	import sys
    	app = QApplication(sys.argv)
    	ui = MyLayoutDialog()
    	ui.show()
    	app.exec_()
    
    コンボボックスでウィジェットを選択することで表示されるウィジェットを切り替えることができます。
    StackedLayout実行結果

レイアウトの中にレイアウトを配置する

QHBoxLayout、QVBoxLayout、QGridLayoutにはaddLayout()メソッドがあり、レイアウトを追加することができます。
# -*- coding: utf-8 -*-
 
from PySide2.QtWidgets import *

class MyLayoutDialog(QDialog):
	def __init__(self, parent=None):
		super(MyLayoutDialog, self).__init__(parent)
		self.setWindowTitle("My Layout Dialog")
		
		# 並べるボタンを作成
		buttonA = QPushButton("Button A")
		buttonB = QPushButton("Button B")
		buttonC = QPushButton("Button C")
		buttonD = QPushButton("Button D")
		buttonE = QPushButton("Button E")
		
		# 垂直方向にボタンを3つ並べたレイアウト
		layoutA = QVBoxLayout()
		layoutA.addWidget(buttonA)
		layoutA.addWidget(buttonB)
		layoutA.addWidget(buttonC)

		# 垂直方向にボタンを2つ並べたレイアウト
		layoutB = QVBoxLayout()
		layoutB.addWidget(buttonD)
		layoutB.addWidget(buttonE)
		
		# 作成済みのレイアウトを水平方向に並べる
		parentLayout = QHBoxLayout()
		parentLayout.addLayout(layoutA)
		parentLayout.addLayout(layoutB)
		
		self.setLayout(parentLayout)

if __name__ == '__main__':
	import sys
	app = QApplication(sys.argv)
	ui = MyLayoutDialog()
	ui.show()
	app.exec_()
LayoutInLayout実行結果

位置とサイズを指定してウィジェットを配置する

一般的ではありませんが親ウィンドウに対する位置とサイズを指定してレイアウトを使用せずにウィジェットを配置することも可能です。

# -*- coding: utf-8 -*-
 
from PySide2.QtWidgets import *

class MyLayoutDialog(QDialog):
	def __init__(self, parent=None):
		super(MyLayoutDialog, self).__init__(parent)
		self.setWindowTitle("My Layout Dialog")
		
		# 親ウィジェットを指定して並べるボタンを作成
		buttonA = QPushButton("Button A", self)
		buttonB = QPushButton("Button B", self)
		buttonC = QPushButton("Button C", self)
		
		# 親ウィンドウ内に対する位置とサイズをそれぞれのボタンに指定
		buttonA.setGeometry(0, 0, 100, 50)
		buttonB.setGeometry(150, 0, 200, 150)
		buttonC.setGeometry(0, 160, 250, 50)

if __name__ == '__main__':
	import sys
	app = QApplication(sys.argv)
	ui = MyLayoutDialog()
	ui.show()
	app.exec_()
AbsolutePosition実行結果