PySide でのレイアウト方法 - XSim

↑ページトップへ

トップ - 技術ドキュメント - PySide 使い方メモ

PySide でのレイアウト方法

更新:2016/3/22
PySide 1.2.4Python 2.7.11

レイアウトの種類

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

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

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

    # -*- coding: utf-8 -*-
     
    from PySide.QtCore import *
    from PySide.QtGui 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 PySide.QtCore import *
    from PySide.QtGui 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 PySide.QtCore import *
    from PySide.QtGui 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 PySide.QtCore import *
    from PySide.QtGui 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 PySide.QtCore import *
    from PySide.QtGui 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()メソッドがあり、レイアウトを追加することができます。
LayoutInLayout.py
# -*- coding: utf-8 -*-
 
from PySide.QtCore import *
from PySide.QtGui 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 PySide.QtCore import *
from PySide.QtGui 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実行結果