파이썬 토이 프로젝트 - Q&A [Pyqt]-3[레이아웃]

지환·2023년 6월 1일
0

python

목록 보기
6/12

레이아웃에는 3가지 방식이 있다.

  1. 절대적배치
  2. 박스레이아웃
  3. 그리드레이아웃

01) 절대적 배치

절대 배치 방식을 사용할 때는 다음의 제약을 이해하고 있어야 합니다.

  1. 창의 크기를 조절해도 위젯의 크기와 위치는 변하지 않는다.
  2. 다양한 플랫폼에서 어플리케이션이 다르게 보일 수 있다.
  3. 어플리케이션의 폰트를 바꾸면 레이아웃이 망가질 수 있다.
  4. 레이아웃을 바꾸고 싶다면 완전히 새로 고쳐야 하며, 이는 매우 번거롭다.

예제

## Ex 4-1. 절대적 배치.

import sys
from PyQt5.QtWidgets import QApplication, QWidget, QLabel, QPushButton


class MyApp(QWidget):

    def __init__(self):
        super().__init__()
        self.initUI()

    def initUI(self):
        label1 = QLabel('Label1', self)
        label1.move(20, 20)
        label2 = QLabel('Label2', self)
        label2.move(20, 60)

        btn1 = QPushButton('Button1', self)
        btn1.move(80, 13)
        btn2 = QPushButton('Button2', self)
        btn2.move(80, 53)

        self.setWindowTitle('Absolute Positioning')
        self.setGeometry(300, 300, 400, 200)
        self.show()


if __name__ == '__main__':
    app = QApplication(sys.argv)
    ex = MyApp()
    sys.exit(app.exec_())
  1. 위젯의 위치를 설정하기 위해 move() 메서드를 사용합니다.

  2. 라벨(label1, label2)과 푸시버튼(btn1, btn2)의 x, y 좌표를 설정함으로써 위치를 조절합니다.

  3. 좌표계는 왼쪽 상단 모서리에서 시작합니다. x 좌표는 왼쪽에서 오른쪽으로 갈수록 커지고, y 좌표는 위에서 아래로 갈수록 커집니다.

구체적인 설명

label1 = QLabel('Label1', self)
label1.move(20, 20)
  1. 라벨을 하나 만들고, x=20, y=20에 위치하도록 옮겨줍니다.
btn1 = QPushButton('Button1', self)
btn1.move(80, 13)
  1. 푸시버튼을 하나 만들고, x=80, y=13에 위치하도록 옮겨줍니다.

02) 박스 레이아웃

  1. QHBoxLayout, QVBoxLayout은 여러 위젯을 수평으로 정렬하는 레이아웃 클래스 입니다.

  2. QHBoxLayout, QVBoxLayout 생성자는 수평, 수직의 박스를 하나 만드는데, 다른 레이아웃 박스를 넣을 수도 있고 위젯을 배치할 수도 있습니다.

  1. 예제 코드에서 위젯의 가운데 아래 부분에 두 개의 버튼을 배치하기 위해 수평, 수직의 박스를 하나씩 사용합니다.

  2. 필요한 공간을 만들기 위해 addStretch() 메서드를 사용하고, 'stretch factor'를 조절해 보겠습니다.

예제

## Ex 4-2. 박스 레이아웃.

import sys
from PyQt5.QtWidgets import QApplication, QWidget, QPushButton, QHBoxLayout, QVBoxLayout


class MyApp(QWidget):

    def __init__(self):
        super().__init__()
        self.initUI()

    def initUI(self):
        okButton = QPushButton('OK')
        cancelButton = QPushButton('Cancel')

        hbox = QHBoxLayout()
        hbox.addStretch(1)
        hbox.addWidget(okButton)
        hbox.addWidget(cancelButton)
        hbox.addStretch(1)

        vbox = QVBoxLayout()
        vbox.addStretch(3)
        vbox.addLayout(hbox)
        vbox.addStretch(1)

        self.setLayout(vbox)

        self.setWindowTitle('Box Layout')
        self.setGeometry(300, 300, 300, 200)
        self.show()


if __name__ == '__main__':
    app = QApplication(sys.argv)
    ex = MyApp()
    sys.exit(app.exec_())
  • 창의 가운데 아래에 두 개의 버튼을 배치시킵니다.
  • 두 개의 버튼은 창의 크기를 변화시켜도 같은 자리에 위치합니다.

구체적인 설명

okButton = QPushButton('OK')
cancelButton = QPushButton('Cancel')

두 개의 버튼을 만들었습니다.

hbox = QHBoxLayout()
hbox.addStretch(1)
hbox.addWidget(okButton)
hbox.addWidget(cancelButton)
hbox.addStretch(1)
  1. 수평 박스를 하나 만들고, 두 개의 버튼과 양 쪽에 빈 공간을 추가합니다.

  2. 이 addStretch() 메서드는 신축성있는 빈 공간을 제공합니다.

  3. 두 버튼 양쪽의 stretch factor가 1로 같기 때문에 이 두 빈 공간의 크기는 창의 크기가 변화해도 항상 같습니다.

vbox = QVBoxLayout()
vbox.addStretch(3)
vbox.addLayout(hbox)
vbox.addStretch(1)
  1. 다음으로 수평 박스(hbox)를 수직 박스(vbox)에 넣어줍니다.

  2. 수직 박스의 stretch factor는 수평 박스를 아래쪽으로 밀어내서 두 개의 버튼을 창의 아래쪽에 위치하도록 합니다.

  3. 이 때에도 수평 박스 위와 아래의 빈 공간의 크기는 항상 3:1을 유지합니다. stretch factor를 다양하게 바꿔보면, 의미를 잘 이해할 수 있습니다

self.setLayout(vbox)
  1. 최종적으로 수직 박스를 창의 메인 레이아웃으로 설정합니다.

03) 그리드 레이아웃

가장 일반적인 레이아웃 클래스는 '그리드 레이아웃(grid layout)'입니다. 이 레이아웃 클래스는 위젯의 공간을 행 (row)과 열 (column)로 구분합니다.

그리드 레이아웃을 생성하기 위해 QGridLayout 클래스를 사용합니다.

예제

## Ex 4-3. 그리드 레이아웃.

import sys
from PyQt5.QtWidgets import (QApplication, QWidget, QGridLayout, QLabel, QLineEdit, QTextEdit)


class MyApp(QWidget):

    def __init__(self):
        super().__init__()
        self.initUI()

    def initUI(self):
        grid = QGridLayout()
        self.setLayout(grid)

        grid.addWidget(QLabel('Title:'), 0, 0)
        grid.addWidget(QLabel('Author:'), 1, 0)
        grid.addWidget(QLabel('Review:'), 2, 0)

        grid.addWidget(QLineEdit(), 0, 1)
        grid.addWidget(QLineEdit(), 1, 1)
        grid.addWidget(QTextEdit(), 2, 1)

        self.setWindowTitle('QGridLayout')
        self.setGeometry(300, 300, 300, 200)
        self.show()


if __name__ == '__main__':
    app = QApplication(sys.argv)
    ex = MyApp()
    sys.exit(app.exec_())
  • 세 개의 라벨, 두 개의 라인 에디터, 하나의 텍스트 에디터를 그리드 형태로 배치했습니다.

구체적인 설명

grid = QGridLayout()
self.setLayout(grid)
  • QGridLayout을 만들고, 어플리케이션 창의 레이아웃으로 설정합니다.
grid.addWidget(QLabel('Title:'), 0, 0)
grid.addWidget(QLabel('Author:'), 1, 0)
grid.addWidget(QLabel('Review:'), 2, 0)
  • addWidget() 메서드의 첫 번째 위젯은 추가할 위젯, 두, 세 번째 위젯은 각각 행과 열 번호를 입력합니다.
  • 세 개의 라벨을 첫 번째 열에 수직으로 배치합니다.
grid.addWidget(QTextEdit(), 2, 1)
  • QTextEdit() 위젯은 QLineEdit() 위젯과 달리 여러 줄의 텍스트를 수정할 수 있는 위젯입니다. 세 번째 행, 두 번째 열에 배치합니다.

출처) https://wikidocs.net/21934

profile
아는만큼보인다.

0개의 댓글