0. 학습 목표

더보기

이번 단계에서는 PySide6에서 화면 위젯을 배치할 때 사용하는 레이아웃(Layout)의 개념을 학습합니다.

 

GUI 프로그램에서는 버튼, 라벨, 입력창 같은 위젯을 화면에 보기 좋게 배치해야 합니다.

이때 위젯의 위치와 크기를 직접 계산해서 배치할 수도 있지만, 창 크기가 바뀌거나 위젯이 추가되면 관리가 어려워집니다.

 

Qt에서는 이런 문제를 해결하기 위해 레이아웃 시스템을 제공합니다.

레이아웃은 부모 위젯 안에서 자식 위젯들의 위치와 크기를 자동으로 관리해 주는 구조입니다.

학습 목표 내용
레이아웃 개념 이해 Layout이 화면 구성과 위젯 배치를 의미한다는 점을 이해합니다.
Qt 레이아웃 관리 이해 부모 위젯 안에서 자식 위젯의 위치와 크기를 자동으로 관리하는 구조를 이해합니다.
주요 레이아웃 종류 파악 QVBoxLayout, QHBoxLayout, QGridLayout, QFormLayout의 차이를 이해합니다.
레이아웃 중첩 이해 복잡한 화면을 만들 때 레이아웃 안에 다른 레이아웃을 넣어 구성하는 방법을 이해합니다.
공간 배분 개념 이해 Stretch, Spacer, SizePolicy가 화면의 빈 공간과 크기 조절에 사용된다는 점을 이해합니다.

이번 단계의 핵심
레이아웃은 위젯을 직접 좌표로 배치하는 방식이 아니라,

부모 위젯 안에서 자식 위젯의 위치와 크기를 자동으로 관리하는 구조입니다.

1. 레이아웃(Layout)이란?

더보기

1.1 Layout의 기본 의미

Layout은 일반적으로 배치, 구성, 배열 방식을 의미합니다.

쉽게 말하면 어떤 요소들을 어디에, 어떤 크기로, 어떤 순서로 놓을 것인지를 정하는 구조입니다.

 

GUI 프로그램에서 Layout은 화면 안에 있는 버튼, 라벨, 입력창 같은 위젯을 어떻게 배치할 것인지 결정하는 역할을 합니다.

Layout
    ↓
무엇을
어디에
어떤 크기로
어떤 순서로
배치할 것인지 정하는 구조

따라서 PySide6에서 레이아웃을 이해한다는 것은 단순히 위젯을 화면에 올리는 방법을 배우는 것이 아닙니다.

GUI 화면 전체의 구조를 설계하는 방법을 배우는 것입니다.

 

 

1.2 GUI에서 레이아웃이 필요한 이유

GUI 화면에는 여러 위젯이 들어갑니다.

예를 들어 로그인 화면에는 아이디 입력창, 비밀번호 입력창, 로그인 버튼, 안내 문구가 필요합니다.

 

이 위젯들을 직접 좌표로 배치하면 처음에는 간단해 보일 수 있습니다.

하지만 창 크기가 바뀌거나 위젯이 추가되면 화면이 쉽게 깨질 수 있습니다.

구분 설명
직접 좌표 배치 위젯의 위치와 크기를 직접 지정합니다. 창 크기가 바뀌면 다시 조정해야 합니다.
레이아웃 배치 레이아웃이 위젯의 위치와 크기를 자동으로 계산하고 배치합니다.
창 크기 변경 레이아웃을 사용하면 창 크기가 바뀌어도 위젯이 자동으로 재배치됩니다.

중요한 점
레이아웃은 위젯을 보기 좋게 놓는 기능뿐만 아니라, 창 크기 변화에 맞춰 화면을 자동으로 정리해 주는 역할도 합니다.

2. Qt의 레이아웃 관리 이해하기

더보기

2.1 부모 위젯과 자식 위젯

Qt에서 화면은 보통 부모 위젯과 자식 위젯의 관계로 구성됩니다.

부모 위젯은 창의 바탕이 되고, 자식 위젯은 그 안에 들어가는 버튼, 라벨, 입력창 같은 요소입니다.

부모 위젯(QWidget)
    ├── QLabel
    ├── QLineEdit
    └── QPushButton

레이아웃은 이 부모 위젯 안에서 자식 위젯들을 어떻게 배치할지 관리합니다.

 

 

2.2 setLayout()의 역할

PySide6에서는 QWidget에 레이아웃을 적용할 수 있습니다.

대표적인 방식은 레이아웃 객체를 만든 뒤, 부모 위젯에 setLayout()으로 적용하는 것입니다.

# 레이아웃 생성
layout = QVBoxLayout()

# 부모 위젯에 레이아웃 적용
parent_widget.setLayout(layout)

setLayout()을 호출하면 해당 레이아웃이 부모 위젯 안에서 자식 위젯의 위치와 크기를 관리합니다.

 

즉, 레이아웃은 부모 위젯의 배치 관리자 역할을 합니다.

부모 위젯
    ↓
setLayout(layout)
    ↓
layout이 자식 위젯의 위치와 크기 관리
    ↓
창 크기가 바뀌어도 자동 재배치

참고
QVBoxLayout(self)처럼 레이아웃을 만들 때 부모 위젯을 바로 넣어 주면, 해당 위젯에 레이아웃이 적용됩니다.

3. 주요 레이아웃 종류

더보기

PySide6에서 자주 사용하는 대표적인 레이아웃은 다음과 같습니다.

레이아웃 역할 설명
QVBoxLayout 세로 배치 위젯을 위에서 아래 방향으로 나열합니다.
QHBoxLayout 가로 배치 위젯을 왼쪽에서 오른쪽 방향으로 나열합니다.
QGridLayout 표 형태 배치 행과 열을 기준으로 위젯을 배치합니다.
QFormLayout 라벨 + 입력 폼 회원가입, 로그인, 설정 화면처럼 이름과 입력창이 짝을 이루는 구조에 적합합니다.

3.1 QVBoxLayout

QVBoxLayout은 위젯을 세로 방향으로 배치합니다.

QVBoxLayout
    ├── 위젯 1
    ├── 위젯 2
    └── 위젯 3

3.2 QHBoxLayout

QHBoxLayout은 위젯을 가로 방향으로 배치합니다.

QHBoxLayout
    └── 위젯 1  |  위젯 2  |  위젯 3

3.3 QGridLayout

QGridLayout은 행과 열을 기준으로 위젯을 배치합니다.

계산기 버튼처럼 규칙적인 표 구조를 만들 때 유용합니다.

QGridLayout

[0,0] [0,1] [0,2]
[1,0] [1,1] [1,2]
[2,0] [2,1] [2,2]

3.4 QFormLayout

QFormLayout은 라벨과 입력 위젯을 한 쌍으로 배치할 때 사용합니다.

회원가입 화면, 설정 화면, 로그인 화면처럼 입력 항목이 많은 화면에 적합합니다.

QFormLayout

이름:      [입력창]
이메일:    [입력창]
비밀번호:  [입력창]

4. 레이아웃 중첩과 공간 제어

더보기

4.1 레이아웃 중첩

복잡한 GUI 화면은 하나의 레이아웃만으로 구성하기 어렵습니다.

이럴 때는 레이아웃 안에 다른 레이아웃을 넣는 레이아웃 중첩 방식을 사용합니다.

QVBoxLayout
    ├── QLabel
    ├── QHBoxLayout
    │       ├── QPushButton
    │       ├── QPushButton
    │       └── QPushButton
    └── QHBoxLayout
            ├── QPushButton
            └── QPushButton

위 구조는 전체 화면은 세로 방향으로 구성하고, 버튼 묶음은 가로 방향으로 배치하는 방식입니다.

 

 

4.2 공간 제어 기능

레이아웃은 위젯을 배치하는 것뿐만 아니라, 빈 공간과 위젯 크기 비율도 제어할 수 있습니다.

항목 역할 예시
Stretch Factor 위젯 간 공간 비율 조절 1 : 2 : 1 비율로 공간 배분
SpacerItem 빈 공간을 늘어나게 함 버튼 사이 간격 벌리기
SizePolicy 위젯의 가로 / 세로 확장 정책 Fixed, Expanding

정리
간단한 화면은 QVBoxLayout, QHBoxLayout만으로도 충분하지만, 복잡한 화면은 중첩 레이아웃과 공간 제어 기능을 함께 사용해야 합니다.

5. 예제 코드

더보기

5.1 실습 준비

이번 예제는 PyCharm에서 진행합니다.

새 Python 프로젝트를 만들고, 프로젝트 가상환경에 PySide6가 설치되어 있는 상태에서 진행합니다.

예제 파일명은 main.py로 작성합니다.

 

 

5.2 main.py 예제 코드

import sys
from PySide6.QtWidgets import (
    QApplication,
    QWidget,
    QLabel,
    QPushButton,
    QVBoxLayout,
    QHBoxLayout
)

app = QApplication(sys.argv)

window = QWidget()
window.setWindowTitle("레이아웃 살펴보기")
window.resize(300, 180)

title_label = QLabel("레이아웃 예제")
description_label = QLabel("버튼을 가로로 배치하고, 전체 화면은 세로로 구성합니다.")

button_ok = QPushButton("확인")
button_cancel = QPushButton("취소")

button_layout = QHBoxLayout()
button_layout.addWidget(button_ok)
button_layout.addWidget(button_cancel)

main_layout = QVBoxLayout()
main_layout.addWidget(title_label)
main_layout.addWidget(description_label)
main_layout.addLayout(button_layout)

window.setLayout(main_layout)

window.show()

sys.exit(app.exec())

 

이 예제는 전체 화면을 세로 방향으로 구성하고, 아래쪽 버튼 영역만 가로 방향으로 배치합니다.

main_layout = QVBoxLayout
    ├── title_label
    ├── description_label
    └── button_layout = QHBoxLayout
            ├── 확인 버튼
            └── 취소 버튼

즉, 이 예제는 QVBoxLayout과 QHBoxLayout을 중첩해서 사용하는 기본 구조를 보여 줍니다.

 

 

5.3 예제에서 확인할 핵심 구조

코드 의미
QVBoxLayout() 위젯을 세로 방향으로 배치합니다.
QHBoxLayout() 위젯을 가로 방향으로 배치합니다.
addWidget() 레이아웃에 위젯을 추가합니다.
addLayout() 레이아웃 안에 다른 레이아웃을 추가합니다.
setLayout() 부모 위젯에 레이아웃을 적용합니다.

 

 

5.4 예제 파일

예제 파일은 main.py로 저장합니다.

 


6. 코드 분석

더보기

6.1 주석 포함 전체 코드

import sys                                      # [1] 파이썬 인터프리터 관련 기능을 제공하는 sys 모듈을 가져옴
from PySide6.QtWidgets import (                 # [2] PySide6의 위젯 관련 클래스들 중에서
    QApplication,                               #     - QApplication: 전체 어플리케이션(프로그램)을 관리하는 클래스
    QWidget,                                    #     - QWidget: 화면에 보이는 기본 창 위젯 클래스
    QLabel,                                     #     - QLabel: 화면에 텍스트를 표시하는 위젯 클래스
    QPushButton,                                #     - QPushButton: 클릭 가능한 버튼 위젯 클래스
    QVBoxLayout,                                #     - QVBoxLayout: 위젯을 세로 방향으로 배치하는 레이아웃 클래스
    QHBoxLayout                                 #     - QHBoxLayout: 위젯을 가로 방향으로 배치하는 레이아웃 클래스
)

app = QApplication(sys.argv)                    # [3] QApplication 객체 생성
                                                #     - 모든 Qt GUI 프로그램은 QApplication 객체가 필요함
                                                #     - sys.argv는 실행 시 명령줄 인자 리스트를 전달함

window = QWidget()                              # [4] 기본 창 위젯 생성
window.setWindowTitle("레이아웃 살펴보기")        # [5] 창 제목 설정
window.resize(300, 180)                         # [6] 창 크기 설정

title_label = QLabel("레이아웃 예제")             # [7] 제목을 표시할 QLabel 생성
description_label = QLabel(                     # [8] 설명 문장을 표시할 QLabel 생성
    "버튼을 가로로 배치하고, 전체 화면은 세로로 구성합니다."
)

button_ok = QPushButton("확인")                  # [9] 확인 버튼 생성
button_cancel = QPushButton("취소")              # [10] 취소 버튼 생성

button_layout = QHBoxLayout()                   # [11] 버튼을 가로로 배치할 QHBoxLayout 생성
button_layout.addWidget(button_ok)              # [12] button_layout에 확인 버튼 추가
button_layout.addWidget(button_cancel)          # [13] button_layout에 취소 버튼 추가

main_layout = QVBoxLayout()                     # [14] 전체 화면을 세로로 구성할 QVBoxLayout 생성
main_layout.addWidget(title_label)              # [15] main_layout에 제목 라벨 추가
main_layout.addWidget(description_label)        # [16] main_layout에 설명 라벨 추가
main_layout.addLayout(button_layout)            # [17] main_layout 안에 button_layout 추가
                                                #      - 레이아웃 안에 다른 레이아웃을 넣는 중첩 구조

window.setLayout(main_layout)                   # [18] window에 main_layout 적용
                                                #      - 이제 main_layout이 window 안의 위젯 배치를 관리함

window.show()                                   # [19] 창을 실제로 화면에 표시

sys.exit(app.exec())                            # [20] 이벤트 루프(Event Loop) 시작
                                                #      - 창이 닫힐 때까지 GUI 이벤트를 계속 처리함

 

 

6.2 단계별 분석

1단계: 필요한 클래스 가져오기

from PySide6.QtWidgets import QApplication, QWidget, QLabel, QPushButton, QVBoxLayout, QHBoxLayout

레이아웃 예제를 만들기 위해 위젯 클래스와 레이아웃 클래스를 함께 가져옵니다.

클래스 역할
QWidget 기본 창을 만듭니다.
QLabel 텍스트를 표시합니다.
QPushButton 버튼을 만듭니다.
QVBoxLayout 위젯을 세로로 배치합니다.
QHBoxLayout 위젯을 가로로 배치합니다.

 

2단계: 위젯 생성

title_label = QLabel("레이아웃 예제")
description_label = QLabel("버튼을 가로로 배치하고, 전체 화면은 세로로 구성합니다.")

button_ok = QPushButton("확인")
button_cancel = QPushButton("취소")

먼저 화면에 표시할 위젯들을 생성합니다.

이 단계에서는 아직 위젯이 화면에 배치된 것은 아닙니다.

생성한 위젯들을 레이아웃에 추가해야 실제 화면 구조가 만들어집니다.

 

3단계: 버튼 영역 가로 레이아웃 만들기

button_layout = QHBoxLayout()
button_layout.addWidget(button_ok)
button_layout.addWidget(button_cancel)

확인 버튼과 취소 버튼은 가로 방향으로 배치합니다.

따라서 QHBoxLayout을 사용합니다.

button_layout = QHBoxLayout
    ├── 확인 버튼
    └── 취소 버튼

 

4단계: 전체 화면 세로 레이아웃 만들기

main_layout = QVBoxLayout()
main_layout.addWidget(title_label)
main_layout.addWidget(description_label)
main_layout.addLayout(button_layout)

전체 화면은 세로 방향으로 구성합니다.

먼저 제목 라벨, 설명 라벨을 위에서 아래로 배치하고, 마지막에 버튼 레이아웃을 추가합니다.

main_layout = QVBoxLayout
    ├── title_label
    ├── description_label
    └── button_layout = QHBoxLayout
            ├── 확인 버튼
            └── 취소 버튼

여기서 중요한 점은 main_layout 안에 button_layout이 들어갔다는 것입니다.

이것이 바로 레이아웃 중첩입니다.

 

5단계: 부모 위젯에 레이아웃 적용

window.setLayout(main_layout)

setLayout()을 호출하면 main_layout이 window의 레이아웃으로 적용됩니다.

이제 window 안의 위젯 위치와 크기는 main_layout이 관리합니다.

중요한 점
위젯을 생성한 것만으로는 화면 배치가 완성되지 않습니다. 위젯을 레이아웃에 추가하고, 그 레이아웃을 부모 위젯에 적용해야 합니다.

7. Qt Designer에서 구현할 때의 구조

더보기

7.1 코드 방식과 Designer 방식의 차이

코드 방식에서는 QVBoxLayout, QHBoxLayout 같은 레이아웃 클래스를 직접 생성합니다.

main_layout = QVBoxLayout()
button_layout = QHBoxLayout()

반면 Qt Designer에서는 화면에서 위젯을 선택한 뒤, 레이아웃 버튼을 눌러 배치 구조를 적용합니다.

즉, 코드로 직접 레이아웃 객체를 만드는 대신 Designer 화면에서 시각적으로 레이아웃을 설정합니다.

구분 코드 방식 Qt Designer 방식
레이아웃 생성 QVBoxLayout(), QHBoxLayout() Designer에서 레이아웃 적용
위젯 추가 addWidget() 드래그 앤 드롭
레이아웃 중첩 addLayout() 위젯 그룹 선택 후 레이아웃 적용
전체 화면 적용 setLayout() 최상위 위젯에 레이아웃 적용

 

 

7.2 Qt Designer 기반 작업 흐름

Qt Designer에서 Widget 생성
        ↓
Label, Button 등 위젯 배치
        ↓
관련 위젯들을 선택
        ↓
가로 / 세로 / 그리드 레이아웃 적용
        ↓
최상위 Widget에도 레이아웃 적용
        ↓
form.ui 저장
        ↓
pyside6-uic으로 ui_form.py 변환

주의할 점
Qt Designer에서 위젯을 화면에 올려놓기만 하면 레이아웃이 적용된 것이 아닙니다. 반드시 레이아웃을 적용해야 창 크기 변경 시 위젯들이 자동으로 정렬됩니다.

8. 정리

더보기

이번 단계에서는 PySide6에서 화면을 구성할 때 사용하는 레이아웃(Layout)의 기본 개념을 살펴보았습니다.

레이아웃은 위젯을 단순히 화면에 놓는 기능이 아니라, 부모 위젯 안에서 자식 위젯의 위치와 크기를 자동으로 관리하는 구조입니다.

위젯 생성
    ↓
레이아웃 생성
    ↓
레이아웃에 위젯 추가
    ↓
부모 위젯에 레이아웃 적용
    ↓
창 크기에 따라 자동 배치
개념 정리
Layout 위젯의 위치와 크기를 관리하는 배치 구조입니다.
QVBoxLayout 위젯을 세로 방향으로 배치합니다.
QHBoxLayout 위젯을 가로 방향으로 배치합니다.
QGridLayout 위젯을 행과 열 기준으로 배치합니다.
QFormLayout 라벨과 입력 위젯을 한 쌍으로 배치합니다.
레이아웃 중첩 복잡한 화면을 만들기 위해 레이아웃 안에 다른 레이아웃을 넣는 구조입니다.
setLayout() 부모 위젯에 레이아웃을 적용합니다.

이번 단계에서 기억할 문장
PySide6에서 레이아웃은 위젯의 위치와 크기를 자동으로 관리하는 화면 배치 시스템입니다.

 

간단한 화면은 QVBoxLayout과 QHBoxLayout으로 시작하고, 복잡한 화면은 레이아웃 중첩과 공간 제어 기능을 함께 사용합니다.

 

참고. 공식 문서로 확인하기

더보기

이번 예제에서 사용한 QVBoxLayout, QHBoxLayout, QGridLayout, QFormLayout, setLayout(), Qt Designer, pyside6-uic는 모두 Qt / PySide6 공식 문서에서 확인할 수 있습니다.

 

특히 이번 단계에서 중요한 부분은 레이아웃이 부모 위젯 안에서 자식 위젯의 위치와 크기를 자동으로 관리한다는 점입니다.

 

1. 공식 문서 참고 표

구분 공식 문서 확인할 내용
Layout 기본 개념 Qt for Python - Layout Management QHBoxLayout, QVBoxLayout, QGridLayout, QFormLayout 같은 기본 레이아웃 관리자를 확인할 수 있습니다.
QLayout PySide6.QtWidgets.QLayout QLayout이 레이아웃 클래스들의 기본 클래스이며, geometry manager 역할을 한다는 점을 확인할 수 있습니다.
QVBoxLayout PySide6.QtWidgets.QVBoxLayout 위젯을 세로 방향으로 배치하는 레이아웃 클래스임을 확인할 수 있습니다.
QHBoxLayout PySide6.QtWidgets.QHBoxLayout 위젯을 가로 방향으로 배치하는 레이아웃 클래스임을 확인할 수 있습니다.
QGridLayout PySide6.QtWidgets.QGridLayout 부모 위젯이나 부모 레이아웃에서 사용할 수 있는 공간을 행과 열로 나누어 위젯을 배치하는 구조를 확인할 수 있습니다.
QFormLayout PySide6.QtWidgets.QFormLayout 라벨과 입력 위젯을 2열 폼 형태로 배치하는 구조를 확인할 수 있습니다.
QWidget.setLayout() PySide6.QtWidgets.QWidget QWidget에 레이아웃을 적용하고, 해당 레이아웃이 위젯의 배치 관리자가 되는 구조를 확인할 수 있습니다.
Qt Designer .ui 파일 Qt for Python - Using .ui files Qt Designer에서 만든 .ui 파일을 PySide6 프로젝트에서 사용하는 방법을 확인할 수 있습니다.
pyside6-uic Qt for Python - pyside6-uic .ui 파일을 .py 파일로 변환하여 Python 클래스처럼 사용하는 도구를 확인할 수 있습니다.

 

2. Layout Management 기본 개념

Qt 공식 문서에서는 위젯을 보기 좋게 배치하는 가장 쉬운 방법으로 기본 레이아웃 관리자를 사용하는 방식을 설명합니다.

대표적인 기본 레이아웃 관리자는 QHBoxLayout, QVBoxLayout, QGridLayout, QFormLayout입니다.

 

이 레이아웃들은 자식 위젯들의 위치와 크기를 직접 좌표로 지정하지 않고, 부모 위젯 안에서 자동으로 배치하고 관리합니다.

부모 위젯
    ↓
레이아웃 적용
    ↓
자식 위젯 추가
    ↓
레이아웃이 위치와 크기 자동 관리

따라서 PySide6에서 레이아웃을 사용하면 창 크기가 바뀌어도 위젯들이 자동으로 재배치될 수 있습니다.

 

3. 주요 레이아웃 클래스

이번 학습자료에서는 PySide6에서 자주 사용하는 주요 레이아웃 클래스를 살펴보았습니다.

각 레이아웃은 위젯을 배치하는 방식이 다릅니다.

레이아웃 배치 방식 사용 예시
QVBoxLayout 위에서 아래로 세로 배치 제목, 설명, 버튼 영역을 세로로 나열
QHBoxLayout 왼쪽에서 오른쪽으로 가로 배치 확인 버튼과 취소 버튼을 가로로 배치
QGridLayout 행과 열 기준의 표 형태 배치 계산기 버튼, 대시보드, 표 형태 화면
QFormLayout 라벨 + 입력 위젯의 2열 폼 배치 로그인, 회원가입, 설정 화면

공식 문서에서도 QVBoxLayout은 위젯을 세로로 정렬하는 레이아웃, QHBoxLayout은 위젯을 가로로 정렬하는 레이아웃으로 설명합니다.

QGridLayout은 사용 가능한 공간을 행과 열로 나누어 위젯을 배치하고, QFormLayout은 라벨과 입력 위젯을 폼 구조로 배치할 때 사용합니다.

 

4. setLayout()과 레이아웃 적용

코드 방식에서는 레이아웃 객체를 만든 뒤, 부모 위젯에 setLayout()으로 적용합니다.

layout = QVBoxLayout()

layout.addWidget(label)
layout.addWidget(button)

window.setLayout(layout)

 

공식 문서에서도 QWidget의 setLayout()은 지정한 레이아웃을 해당 위젯의 레이아웃 관리자로 설정하는 기능으로 설명됩니다.

즉, setLayout()을 호출하면 해당 레이아웃이 부모 위젯 내부의 자식 위젯 배치를 관리하게 됩니다.

QWidget
    ↓ setLayout(layout)
QLayout
    ↓
자식 위젯 위치와 크기 관리

또는 다음처럼 레이아웃을 만들 때 부모 위젯을 바로 넣어 주는 방식도 사용할 수 있습니다.

layout = QVBoxLayout(window)

이 방식은 별도로 window.setLayout(layout)을 호출하지 않아도 해당 위젯에 레이아웃을 적용하는 방식으로 이해할 수 있습니다.

 

정리

이번 단계에서 사용하는 레이아웃 구조는 공식 문서 기준으로 다음과 같이 연결됩니다.

QWidget
    ↓ setLayout()
QLayout
    ↓
QVBoxLayout / QHBoxLayout / QGridLayout / QFormLayout
    ↓
addWidget() / addLayout()
    ↓
자식 위젯의 위치와 크기 자동 관리
    ↓
창 크기 변경 시 자동 재배치

즉, PySide6에서 레이아웃은 위젯을 직접 좌표로 배치하는 방식이 아니라, 부모 위젯 안에서 자식 위젯의 위치와 크기를 자동으로 관리하는 화면 배치 시스템입니다.