윈도우 탐색기는 크게 폴더트리 부분과 폴더의 내용을 보여주는 부분으로 나눠져 있습니다.
폴더트리와 폴더의 내용을 보여주는 부분에는 희미하게 회색으로 세로방향 선이 그어져 있는데, 그냥 보면 잘 안 보여서 검은색 굵은 라인으로 그렸습니다. 이 선을 좌우로 움직이면서 폴더트리 부분을 크게 볼 수도 있고, 반대로 폴더의 내용을 더 크게 볼 수 도 있습니다.
위 예시는 폴더트리 부분을 크게 보고 폴더의 내용창 부분을 작게 줄인 것 입니다.
이처럼 UI에서는 서로 다른 역할을 하는 두 부분을 동시에 보여줘야할 일이 있습니다. 그리고 사용자의 편의를 위해서 그 두 부분의 영역의 넓이를 위와 같이 조절할 수 있는 기능이 있어야 합니다.
PyQt GUI에서는 QFrame이라는 위젯을 이용해서 위 기능을 수행합니다. Frame은 우리말로 "틀" 또는 "액자"를 뜻하는데, 하나의 UI에 여러개의 액자를 두고 각 액자의 크기를 원하는 용도에 맞게 조절하는 방법입니다. 이번 포스팅에서는 QFrame 위젯을 이용하여 위와 같이 하나의 메인 레이아웃에 여러개의 Frame을 만드는 것을 알아보겠습니다.
우선 전체 코드는 아래와 같습니다. 아래 코드를 복-붙 한다음에 프로그램을 실행하면 됩니다.
import sys
from PyQt5.QtGui import *
from PyQt5.QtCore import *
from PyQt5.QtWidgets import *
class Main(QDialog):
def __init__(self):
super().__init__()
self.init_ui()
def init_ui(self):
main_layout = QVBoxLayout()
frame_1 = QFrame()
frame_1.setFrameShape(QFrame.Panel | QFrame.Sunken)
frame_2 = QFrame()
frame_2.setFrameShape(QFrame.Panel | QFrame.Sunken)
layout_1 = QVBoxLayout()
layout_2 = QVBoxLayout()
button_1 = QPushButton("button_1")
button_2 = QPushButton("button_2")
layout_1.addWidget(button_1)
layout_2.addWidget(button_2)
frame_1.setLayout(layout_1)
frame_2.setLayout(layout_2)
spliter_1 = QSplitter(Qt.Horizontal)
spliter_1.addWidget(frame_1)
spliter_1.addWidget(frame_2)
main_layout.addWidget(spliter_1)
self.setLayout(main_layout)
self.resize(500, 500)
self.show()
if __name__ == '__main__':
app = QApplication(sys.argv)
main = Main()
sys.exit(app.exec_())
위 프로그램을 실행하면 아래와 같은 UI를 얻을 수 있습니다.
좌-우 두개의 틀(Frame)이 생긴것이 보이는지요? 그리고 중간에 있는 세로 방향의 구분자를 좌우로 이동시키면 좌우 틀의 크기를 마음대로 조절할 수 있습니다. 이 코드에서는 두 개의 Frame을 생성하고, 이 두 프레임을 QSpliter를 생성하여 QSpliter에 추가한 것 입니다. 즉, 가장 작은 요소 부터 큰 요소 순서대로 정렬을 하면
위젯 -> 레이아웃 -> 프레임 -> 스플리터 -> 레이아웃
순서대로 구성 요소들을 만들어 최종 UI를 형성하는 것 입니다. 반대로 큰 요소 부터 설명하면 (항상 나오는 위젯 -> 레이아웃과 최종적으로 생성하게 되는 메인 레이아웃은 당연하니 생략하도록 하겠습니다),
수평방향 스플리터를 생성하여, 이 스플리터에 frame_1과 frame_2를 추가한다.
frame_1과 frame_2에는 각각 layout_1, layout_2를 설정한다
입니다. 이 부분에 해당하는 코딩은 (즉, 이번 포스팅의 핵심적인 코딩은) 아래와 같습니다.
frame_1 = QFrame() # 프레임 생성
frame_1.setFrameShape(QFrame.Panel | QFrame.Sunken) # 프레임 스타일 설정
layout_1 = QVBoxLayout()
button_1 = QPushButton("button_1")
layout_1.addWidget(button_1) # 프레임에 넣을 레이아웃 생성
frame_1.setLayout(layout_1) # 생성한 레이아웃을 프레임에 적용
spliter_1 = QSplitter(Qt.Horizontal) #스플리터 생성
spliter_1.addWidget(frame_1) #스플리터에 frame_1 추가
spliter_1.addWidget(frame_2) #스플리터에 frame_2 추가
main_layout.addWidget(spliter_1) #스플리터 위젯을 메인 레이아웃에 추가
당연히 layout_1에는 원하는 레이아웃을 생성해 주면 됩니다. 최종적으로 main_layout에 적용이 되는 위젯은 스플리터 위젯으로 이 예시에서는 Horizontal 방향의 스플릿을 설정하였습니다. 스플리터는 Qt.Horizontal을 통해서 좌우 방향의 스플리터를 만들 수 있고, Qt.Vertical를 통해서 위아래 방향의 스플리터를 만들 수 있습니다.
코드의 윗 부분에
frame_1.setFrameShape(QFrame.Panel | QFrame.Sunken)
는 프레임의 스타일을 정해주는 것인데,
와 같은 옵션으로 스타일을 설정할 수 있습니다.
스플리터와 프레임을 활용하여 전체 UI를 만드는 것은 마치 QVBoxLayout, QHBoxLayout을 이용하여 위젯을 배치하는 것과 방법적으로 보면 별반 차이가 없습니다. 즉 스플리터가 레이아웃에 대응되고, 프레임이 위젯이 대응된다고 할 수 있습니다.
QVBoxLayout, QHBoxLayout를 소개하는 포스팅에서 두 레이아웃을 함께 사용하여 다양한 형태로 위젯을 배치하였던 것 처럼, 여러개의 Horizontal, Vertical 스플리터를 이용하여 원하는 형태의 다양한 프레임 배치를 할 수 있습니다.
위 UI는 Vertical 스플리터와 Horizontal 스플리터를 활용하여 전체창을 3분할 한 UI입니다. 핵심적인 코딩은
spliter_1 = QSplitter(Qt.Horizontal)
spliter_1.addWidget(frame_1)
spliter_1.addWidget(frame_2)
spliter_2 = QSplitter(Qt.Vertical)
spliter_2.addWidget(spliter_1)
spliter_2.addWidget(frame_3)
main_layout.addWidget(spliter_2)
와 같습니다. 우선 위 두 프레임을 spliter_1를 통해서 구성하고, spliter_2에서는 앞서 만든 spliter_1과 아래 부분의 frame_3을 추가하였습니다. 앞서 언급한대로 QHBoxLayout과 QVBoxLayout을 이용하여 위젯을 배치한것과 크게 다르지 않습니다.
화면 중간에 있는 가로, 세로 스플리터바를 통해서 프레임의 크기를 원하는대로 조절할 수 있습니다. 물론 각 프레임에 설정 돼 있는 레이아웃이나 위젯의 크기 정책에 따라서 프레임의 크기 변경에 제한이 있을 수 도 있습니다.
프레임의 사이즈(비율)이 초기값은 아래와 같은 문법으로 지정할 수 있습니다.
spliter_1.setSizes([100, 200])
spliter_2.setSizes([100, 200])
이렇게 하면, spliter_1은 기본적으로 100:200 의 비율로 프레임의 크기가 정해지고, spliter_2 역시 기본적으로 100:200 의 비율로 프레임의 크기가 정해집니다. 위 설정을 추가하고 프로그램을 실행하면,
와 같이 프레임의 크기가 적용 되었음을 확인할 수 있습니다.
'PyQt GUI' 카테고리의 다른 글
PyQt GUI (10) : StyleSheet 설정을 통해 계산기 꾸미기 - setStyleSheet (0) | 2021.08.06 |
---|---|
PyQt GUI (9) : 텝을 이용하여 GUI를 알차게 꾸미기 - QTabWidget (0) | 2021.08.06 |
PyQt GUI (7) : 그룹박스를 사용하여 UI 구성 다양하게 하기 - QGroupBox (0) | 2021.08.05 |
PyQt GUI (6) : GUI창의 크기에 따라 위젯의 크기가 자동으로 커지게 하기 (1) | 2021.08.05 |
PyQt GUI (5) 어플리케이션 만들기 (1) : 100줄만에 계산기 만들기 (1) | 2021.08.04 |