본문 바로가기

PyQt GUI

PyQt GUI (2) : 레이아웃을 이용한 위젯 배치 - QVBoxLayout, QHBoxLayout, QGridLayout 사용법

728x90

https://youtu.be/A2S9TQV0wuk

GUI에서 가장 중요한 것 중에 하나는 위젯을 원하는 위치에 배치하는 것입니다. 지난 포스팅 (1) PyQt GUI Hello World에서는 위젯을 소개하는것이 주요 내용이었다면, 이번 포스팅에서는 QVBoxLayout, QHBoxLayout을 이용하여 위젯을 배치하는 것을 소개하도록 하겠습니다. 

네이버 사전에서 "layout"을 검색하면 [배치]라는 의미가 나옵니다. 앞에서 언급한 바와 같이 layout은 위젯을 "배치" 하는 것 인데요. PyQt에서 가장 많이 이용하는 layout의 종류로는

 

QHBoxLayout : 위젯을 가로방향(수평방항 horizontal)으로 나란하게 배치

QVBoxLayout : 위젯을 세로방향(수직방향 vertical)으로 나란하개 비치

QGridLayout : 바둑판 모양으로 위젯을 배치

QFormLayout : 하나의 행(row)에 라벨(label)과 필드(field)를 이용하여 세로방향으로 순차적으로 배치

 

가 있습니다. 특히 이번 포스팅에서는 QHBoxLayout,  QVBoxLayout, QGridLayout을 사용하여 위젯을 배치하는 것을 알아 보겠습니다. QFormLayout은 조금 특수한 형태의 Layout이니 다음 포스팅에서 차차 알아가도록 하겠습니다. 

 

전체 코드는 아래와 같습니다.

import sys
from PyQt5.QtWidgets import *

class Main(QDialog):
    def __init__(self):
        super().__init__()
        self.init_ui()

    def init_ui(self):
        layout = QHBoxLayout()

        button_1 = QPushButton("button_1")
        button_2 = QPushButton("button_2")

        layout.addWidget(button_1)
        layout.addWidget(button_2)

        self.setLayout(layout)
        self.resize(500, 500)
        self.show()

if __name__ == '__main__':
    app = QApplication(sys.argv)
    main = Main()
    sys.exit(app.exec_())

위 코드를 실행하면, 

와 같이 button_1과 button_2가 가로방향으로 나란하게 배치된 UI가 실행됩니다. 

 

위 코드는 가장 간단한 형태의 QHBoxLayout의 사용법 입니다. 만일 button_1과 button_2를 나란하게 수평방향으로 배치하고 싶다면, QHBoxLayout을 사용하면 됩니다. QHBoxLayout을 생성하고, 미리 생성한 button_1과 button_2를 addWidget을 통해서 layout에 추가합니다. 세 개 혹은 그 이상 원하는 만큼의 위젯을 addWidget을 통해 하나의 레이아웃에 포함시킬 수 있습니다. 

 

이 코드에서는 위젯의 예시로 QPushButton을 사용했는데요, 실제 UI에서는 QLineEdit, QComboBox등 원하는 종류의 위젯을 사용하면 됩니다. 

 

레이아웃에 다른 레이아웃을 추가하여 보다 복잡한 형태의 위젯 배치를 구현할 수 도 있습니다. 

    def init_ui(self):
        layout = QHBoxLayout()

        button_1 = QPushButton("button_1")
        button_2 = QPushButton("button_2")
        button_3 = QPushButton("button_3")

        layout_1 = QVBoxLayout()
        layout_1.addWidget(button_1)
        layout_1.addWidget(button_2)

        layout.addWidget(button_3)
        layout.addLayout(layout_1)

        self.setLayout(layout)
        self.resize(500, 500)
        self.show()

전체 코드에서 실제로 레이아웃과 위젯을 만드는 init_ui 메소드입니다. 위 코드를 실행하면,

와 같은 위젯 button_1, button_2, button_3의 배치를 얻을 수 있습니다. 위 코드를 보면 직관적으로 이해가 되지만 한 번 더 설명하면, 우선 button_1과 button_2를 QVBoxLayout layout_1을 이용하여 세로방향으로 배치합니다. 그리고 button_3과 layout_1를 QHBoxLayout layout을 이용하여 가로방향으로 배치합니다. 레이아웃에 위젯을 추가할 때는 .addWidget을, 레이아웃에 다른 레이아웃을 추가할 때는 .addLayout을 사용하면 됩니다. 원리적으로 보면 위 두 QHBoxLayout과 QVBoxLayout만 있으면 원하는 형태의 모든 위젯 배치를 구성할 수 있습니다. 

 

QGridLayout은 주로 대등한 관계의 위젯을 바둑판 모양으로 배치하는데 사용됩니다. 

    def init_ui(self):
        layout = QGridLayout()

        button_1 = QPushButton("button_1")
        button_2 = QPushButton("button_2")
        button_3 = QPushButton("button_3")
        button_4 = QPushButton("button_4")
        button_5 = QPushButton("button_5")
        button_6 = QPushButton("button_6")

        layout.addWidget(button_1, 0, 0)
        layout.addWidget(button_2, 0, 1)
        layout.addWidget(button_3, 0, 2)
        layout.addWidget(button_4, 1, 0)
        layout.addWidget(button_5, 1, 1)
        layout.addWidget(button_6, 1, 2)

        self.setLayout(layout)
        self.resize(500, 500)
        self.show()

역시나 전체 코드에서 실제로 레이아웃과 위젯을 만드는 init_ui 메소드입니다. 위 코드를 실행하면,

와 같이 button_1 ~ button_6 여섯개의 위젯이 2행 3열 형태의 배치를 갖게 됩니다. QGridLayout을 만들고 이 레이아웃에 addWidget(위젯, 행, 렬)과 같은 문법으로 원하는 위젯을 (행,렬) 위치에 넣을 수 있습니다. 물론 앞에서 다룬 QHBoxLayout과 QVBoxLayout을 이용하여,

    def init_ui(self):
        layout = QVBoxLayout()

        button_1 = QPushButton("button_1")
        button_2 = QPushButton("button_2")
        button_3 = QPushButton("button_3")
        button_4 = QPushButton("button_4")
        button_5 = QPushButton("button_5")
        button_6 = QPushButton("button_6")

        layout_1 = QHBoxLayout()
        layout_2 = QHBoxLayout()

        layout_1.addWidget(button_1)
        layout_1.addWidget(button_2)
        layout_1.addWidget(button_3)

        layout_2.addWidget(button_4)
        layout_2.addWidget(button_5)
        layout_2.addWidget(button_6)

        layout.addLayout(layout_1)
        layout.addLayout(layout_2)

        self.setLayout(layout)
        self.resize(500, 500)
        self.show()

와 같이하면 같은 형태의 위젯 배치가 얻어지지만, 코드에서 보면 알 수 있듯, QGridLayout을 사용하는 편이 훨씬 더 간단하게 원하는 위젯 배치를 할 수 있음을 확인할 수 있습니다. 

728x90