본문으로 바로가기

파이썬(Python) PyQt5 QFrame 구현하기

category 파이썬/PyQt5 2021. 11. 10. 18:13
반응형

QFrame 은 화면에서 영역을 구분 지을 때 틀을 만드는 위젯으로 내부에 어떤 컨텐츠를 가지고 있지 않아도 생성이 가능합니다. 쉽게 말해서 액자입니다. 틀을 구성하는 디자인은 크게 두 부분으로 나눠지는데, 프레임의 모양과 그림자 유형입니다.

 

1. 기본 QFrame 화면에 추가하기

 

먼저 프레임 모양의 파라미터 상수값들은 아래와 같습니다.  

 

그림자 유형인 Shadow 의 상수값은 다음과 같습니다.

 

프레임 모양과 그림자 유형을 적용했을 때 어떻게 적용되는지 알 수 있는 표입니다.

 

프레임의 모양과 그림자 유형을 하나 골라서 QFrame 을 추가해 보았습니다. 프레임 모양은 setFrameShape() 함수이며, 그림자 유형의 적용을 위해서 setFrameShadow() 를 사용합니다.

#-*- coding: utf-8 -*-
import sys
from PyQt5.QtWidgets import QMainWindow, QApplication, QFrame

class MainWindow(QMainWindow):
    def __init__(self):
        super().__init__()
        # 윈도우 설정
        self.setGeometry(200, 100, 300, 300)  # x, y, w, h
        self.setWindowTitle('QFrame Window')

        # QFrame 추가
        self.frame = QFrame(self)
        self.frame.setGeometry(10, 10, 200, 200)
        self.frame.setFrameShape(QFrame.Box)
        self.frame.setFrameShadow(QFrame.Raised)

if __name__ == '__main__':
    app = QApplication(sys.argv)
    mainWindow = MainWindow()
    mainWindow.show()
    sys.exit(app.exec_())

 

적용 결과는 다음과 같습니다. 다음은 좀더 뚜렷한 구분을 위해 테두리를 수정해 보겠습니다.

 

2. 테두리 수정하기

 

QFrame 모양을 구성하는 테두리의 속성은 3가지인데, lineWidth midLineWidth, frameWidth 입니다.

  • lineWidth : 프레임 테두리의 너비입니다.
  • midLineWidth : 프레임 중앙에 추가로 들어가는 선이며, 그림자 옵션인 Raised, Sunken 에만 적용이 됩니다. 그림자 효과를 표현할 때 사용하는 선입니다. 이것으로 3D 효과를 얻을 수 있습니다.
  • frameWidth : lineWidth 과 midLineWidth 의 합을 말합니다. Shape 와 Shadow 모두 적용하지 않은 NoFrame 인 경우 값은 0 이 됩니다.

아래 그림은 lineWidth = 20, midLineWidth = 0 일 때와 midLineWidth = 10 일 때를 비교한 화면입니다. 외곽 라인과 그림자 중간 부분이 늘어났습니다. 왼쪽과 오른쪽의 frameWidth 은 각각 20 30 입니다.

#-*- coding: utf-8 -*-
import sys
from PyQt5.QtWidgets import QMainWindow, QApplication, QFrame

class MainWindow(QMainWindow):
    def __init__(self):
        super().__init__()
        # 윈도우 설정
        self.setGeometry(200, 100, 300, 300)  # x, y, w, h
        self.setWindowTitle('QFrame Window')

        # QFrame 추가
        self.frame = QFrame(self)
        self.frame.setGeometry(10, 10, 200, 200)
        self.frame.setFrameShape(QFrame.Box)
        self.frame.setFrameShadow(QFrame.Raised)
        self.frame.setLineWidth(20)
        self.frame.setMidLineWidth(10)

        print(self.frame.frameWidth())
if __name__ == '__main__':
    app = QApplication(sys.argv)
    mainWindow = MainWindow()
    mainWindow.show()
    sys.exit(app.exec_())

 

3. QFrame 두 개 이상 배치하기

 

QFrame 개체가 여러 개일 때 화면에 배치하는 방법은 여러가지입니다. 어떤 Layout 위젯을 쓰는지에 따라 달라질 수 있습니다. 샘플 예제는 QVBoxLayout 을 사용했습니다. 먼저 추가할 QFrame 2개를 생성해서 QVBoxLayout 위젯 객체에 추가합니다. 함수는 addWidget() 입니다.

# 첫 번째 QFrame 추가
self.frame1 = QFrame()
self.frame1.setFrameShape(QFrame.Box)
self.frame1.setFrameShadow(QFrame.Raised)
self.frame1.setLineWidth(10)
self.frame1.setMidLineWidth(1)

# 두 번째 QFrame 추가
self.frame2 = QFrame()
self.frame2.setFrameShape(QFrame.StyledPanel)
self.frame2.setFrameShadow(QFrame.Plain)

# 화면 배치 레이아웃 QVBoxLayout 에 QFrame 추가
vboxlayout = QVBoxLayout()
vboxlayout.addWidget(self.frame1)
vboxlayout.addWidget(self.frame2)

 

다음은 QMainWindow 에 추가하기 위해 QWidget 객체를 생성합니다. 위에서 만든 QVBoxLayout  QWidget 에 추가합니다.  QWidget QMainWindow setCentralWidget() 을 이용해서 화면에 추가합니다.

# 화면 배치 레이아웃 QVBoxLayout 에 QFrame 추가
vboxlayout = QVBoxLayout()
vboxlayout.addWidget(self.frame1)
vboxlayout.addWidget(self.frame2)

# 위젯을 생성해서 QVBoxLayout 을 추가한다.
widget = QWidget()
widget.setLayout(vboxlayout)

# QMainWindow 에 위젯을 추가한다.
self.setCentralWidget(widget)

 

전체 소스는 다음과 같습니다.

#-*- coding: utf-8 -*-
import sys
from PyQt5.QtWidgets import QMainWindow, QApplication, QFrame, QVBoxLayout, QWidget

class MainWindow(QMainWindow):
    def __init__(self):
        super().__init__()
        # 윈도우 설정
        self.setGeometry(200, 100, 500, 500)  # x, y, w, h
        self.setWindowTitle('QFrame Window')

        # 첫 번째 QFrame 추가
        self.frame1 = QFrame()
        self.frame1.setFrameShape(QFrame.Box)
        self.frame1.setFrameShadow(QFrame.Raised)
        self.frame1.setLineWidth(10)
        self.frame1.setMidLineWidth(1)

        # 두 번째 QFrame 추가
        self.frame2 = QFrame()
        self.frame2.setFrameShape(QFrame.StyledPanel)
        self.frame2.setFrameShadow(QFrame.Plain)

        # 화면 배치 레이아웃 QVBoxLayout 에 QFrame 추가
        vboxlayout = QVBoxLayout()
        vboxlayout.addWidget(self.frame1)
        vboxlayout.addWidget(self.frame2)

        # 위젯을 생성해서 QVBoxLayout 을 추가한다.
        widget = QWidget()
        widget.setLayout(vboxlayout)

        # QMainWindow 에 위젯을 추가한다.
        self.setCentralWidget(widget)

if __name__ == '__main__':
    app = QApplication(sys.argv)
    mainWindow = MainWindow()
    mainWindow.show()
    sys.exit(app.exec_())

 

결과는 다음과 같습니다.

 

4. QFrame 에 위젯 컨트롤 추가하기

 

입력박스나 라벨 같은 컨트롤을 QFrame 에 올리기 위해서는 Layout 위젯이 필요합니다. Layout 위젯은 QBoxLayout, QVBoxLayout, QGridLayout 등을 말합니다. 이곳에 컨트롤을 추가해서 Layout 객체를 만듭니다. 그리고 QFrame setLayout() 함수를 이용해서 추가합니다.

# frame1 에 추가할 QVBoxLayout
frame_layout1 = QVBoxLayout()
frame_layout1.addWidget(QTextEdit())
frame_layout1.addWidget(QTextEdit())

# 첫 번째 QFrame 추가
self.frame1 = QFrame()
self.frame1.setLayout(frame_layout1) # 위젯 추가

# frame2 에 추가할 QVBoxLayout
frame_layout2 = QVBoxLayout()
frame_layout2.addWidget(QLabel('QLabel frame add1'))
frame_layout2.addWidget(QLabel('QLabel frame add2'))

# 두 번째 QFrame 추가
self.frame2 = QFrame()
self.frame2.setLayout(frame_layout2)

 

레이아웃과 컨트롤을 올린 2 개의 QFrame QVBoxLayout addWidget 을 이용해서 추가합니다. 마지막으로 QMainWindow setCentralWidget() 함수로 화면에 표시합니다.

#-*- coding: utf-8 -*-
import sys
from PyQt5.QtWidgets import QMainWindow, QApplication, QFrame, \
    QVBoxLayout, QWidget, QTextEdit, QLabel

class MainWindow(QMainWindow):
    def __init__(self):
        super().__init__()
        # 윈도우 설정
        self.setGeometry(200, 100, 500, 500)  # x, y, w, h
        self.setWindowTitle('QFrame Window')

        # frame1 에 추가할 QVBoxLayout
        frame_layout1 = QVBoxLayout()
        frame_layout1.addWidget(QTextEdit())
        frame_layout1.addWidget(QTextEdit())

        # 첫 번째 QFrame 추가
        self.frame1 = QFrame()
        self.frame1.setFrameShape(QFrame.Box)
        self.frame1.setFrameShadow(QFrame.Raised)
        self.frame1.setLineWidth(10)
        self.frame1.setMidLineWidth(1)
        self.frame1.setLayout(frame_layout1) # 위젯 추가

        # frame2 에 추가할 QVBoxLayout
        frame_layout2 = QVBoxLayout()
        frame_layout2.addWidget(QLabel('QLabel frame add1'))
        frame_layout2.addWidget(QLabel('QLabel frame add2'))

        # 두 번째 QFrame 추가
        self.frame2 = QFrame()
        self.frame2.setFrameShape(QFrame.StyledPanel)
        self.frame2.setFrameShadow(QFrame.Plain)
        self.frame2.setLayout(frame_layout2)

        # 화면 배치 레이아웃 QVBoxLayout 에 QFrame 추가
        vboxlayout = QVBoxLayout()
        vboxlayout.addWidget(self.frame1)
        vboxlayout.addWidget(self.frame2)

        # 위젯을 생성해서 QVBoxLayout 을 추가한다.
        widget = QWidget()
        widget.setLayout(vboxlayout)

        # QMainWindow 에 위젯을 추가한다.
        self.setCentralWidget(widget)

if __name__ == '__main__':
    app = QApplication(sys.argv)
    mainWindow = MainWindow()
    mainWindow.show()
    sys.exit(app.exec_())

반응형