레이아웃에는 3가지 방식이 있다.
절대 배치 방식을 사용할 때는 다음의 제약을 이해하고 있어야 합니다.
## 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_())
위젯의 위치를 설정하기 위해 move() 메서드를 사용합니다.
라벨(label1, label2)과 푸시버튼(btn1, btn2)의 x, y 좌표를 설정함으로써 위치를 조절합니다.
좌표계는 왼쪽 상단 모서리에서 시작합니다. x 좌표는 왼쪽에서 오른쪽으로 갈수록 커지고, y 좌표는 위에서 아래로 갈수록 커집니다.
label1 = QLabel('Label1', self)
label1.move(20, 20)
btn1 = QPushButton('Button1', self)
btn1.move(80, 13)
QHBoxLayout, QVBoxLayout은 여러 위젯을 수평으로 정렬하는 레이아웃 클래스 입니다.
QHBoxLayout, QVBoxLayout 생성자는 수평, 수직의 박스를 하나 만드는데, 다른 레이아웃 박스를 넣을 수도 있고 위젯을 배치할 수도 있습니다.
예제 코드에서 위젯의 가운데 아래 부분에 두 개의 버튼을 배치하기 위해 수평, 수직의 박스를 하나씩 사용합니다.
필요한 공간을 만들기 위해 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)
수평 박스를 하나 만들고, 두 개의 버튼과 양 쪽에 빈 공간을 추가합니다.
이 addStretch() 메서드는 신축성있는 빈 공간을 제공합니다.
두 버튼 양쪽의 stretch factor가 1로 같기 때문에 이 두 빈 공간의 크기는 창의 크기가 변화해도 항상 같습니다.
vbox = QVBoxLayout()
vbox.addStretch(3)
vbox.addLayout(hbox)
vbox.addStretch(1)
다음으로 수평 박스(hbox)를 수직 박스(vbox)에 넣어줍니다.
수직 박스의 stretch factor는 수평 박스를 아래쪽으로 밀어내서 두 개의 버튼을 창의 아래쪽에 위치하도록 합니다.
이 때에도 수평 박스 위와 아래의 빈 공간의 크기는 항상 3:1을 유지합니다. stretch factor를 다양하게 바꿔보면, 의미를 잘 이해할 수 있습니다
self.setLayout(vbox)
가장 일반적인 레이아웃 클래스는 '그리드 레이아웃(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)
grid.addWidget(QLabel('Title:'), 0, 0)
grid.addWidget(QLabel('Author:'), 1, 0)
grid.addWidget(QLabel('Review:'), 2, 0)
grid.addWidget(QTextEdit(), 2, 1)