ABOUT ME

-

Today
-
Yesterday
-
Total
-
  • Day 7. PyQt5 (Layouts)
    <개인공부> - IT/[Python] 2021. 3. 19. 03:45
    반응형

    앞서 정리한 포스트들은 통해서 어떠한 위젯이 있는지 간단하게 알아보았다. 하지만 단일 위젯은 사용에 제한적이고 더불어 미적으로도 Layout 없이 사용하는 것은 예쁘지 않다. QHBoxLayout, QVBoxLayout, QGridLayout, QStackedLayout 이렇게 4가지 Layout을 사용할 수 있다. 이름에서 보는 것처럼 수평으로 위젯을 구성하는 Layout이면 QHBoxLayout을 사용하고 반대로 수직으로 구성한다면 QVBoxLayout을 사용할 수 있다. QGridLayout은 행렬과 같이 행과 열이 있는 Layout을 떠오르면 쉽고 QStackedLayout은 동일 화면에 여러 위젯이 쌓여있는 형태로 보면 된다. 자세한 내용은 예제 코드로 함께 정리해보고자 한다. 물론 각 Layout을 hardcoding 하지않고 Qt Designer를 사용하면 예쁘게 디자인 할 수 있다.

     

    1. QVBoxLayout

    위의 스냅샷처럼 QVBoxLayout은 위에서부터 위젯이 채워지는 형태의 Layout이다. 한 가지 알아두어야 하는 점이 있는데 QMainWindow에 위젯을 추가하고 싶다면 빈 QWidget에 적용해야 한다.

    # layout_colorwidget.py
    
    from PyQt5.QtGui  import QColor, QPalette
    from PyQt5.QtWidgets import QWidget
    
    class Color(QWidget):
        def __init__(self, color):
            super().__init__()
            self.setAutoFillBackground(True)
    
            palette = self.palette()
            palette.setColor(QPalette.Window, QColor(color))
            self.setPalette(palette)
    import sys
    
    from PyQt5.QtCore import Qt
    from PyQt5.QtWidgets import QApplication, QMainWindow, QVBoxLayout, QWidget
    
    from layout_colorwidget import Color
    
    class MainWindow(QMainWindow):
        def __init__(self):
            super().__init__()
            self.setWindowTitle("My App")
    
            layout = QVBoxLayout()
            layout.addWidget(Color("red"))
            layout.addWidget(Color("green"))
            layout.addWidget(Color("blue"))
            
            widget = QWidget()
            widget.setLayout(layout)
    
            self.setCentralWidget(widget)
    
    app = QApplication(sys.argv)
    
    window = MainWindow()
    window.show()
    
    app.exec_()

    위와 같이 세 가지 색깔의 위젯을 Layout에 추가해주면 아래와 같이 수평적으로 정렬된 위젯이 출력된다.

     

    2. QHBoxLayout

    QHBoxLayout은 왼쪽부터 오른쪽으로 차례대로 위젯이 채워져가는 구성이다. 실행화면은 아래와 같다. QVBoxLayout으로 선언된 부부만 QHBoxLayout으로 변경하고 된다.

     

    세로와 가로로 정렬되는 Layout을 보았으니 이번에는 아래 그림과 같이 두 가지를 혼합해 보면 어떨까? 

     

    import sys
    
    from PyQt5.QtCore import Qt
    from PyQt5.QtWidgets import (
        QApplication, 
        QMainWindow, 
        QHBoxLayout, 
        QVBoxLayout,
        QWidget,
        QLabel
    )
    
    from layout_colorwidget import Color
    
    class MainWindow(QMainWindow):
        def __init__(self):
            super().__init__()
            self.setWindowTitle("My App")
    
            layout1 = QHBoxLayout()
            layout2 = QVBoxLayout()
            layout3 = QVBoxLayout()
    
            layout2.addWidget(Color("red"))
            layout2.addWidget(Color("yellow"))
            layout2.addWidget(Color("purple"))
    
            layout1.addLayout(layout2)
    
            layout1.addWidget(Color("green"))
            
            layout3.addWidget(Color("red"))
            layout3.addWidget(Color("purple"))
    
            layout1.addLayout(layout3)
    
            widget = QWidget()
            widget.setLayout(layout1)
    
            self.setCentralWidget(widget)
    
    app = QApplication(sys.argv)
    
    window = MainWindow()
    window.show()
    
    app.exec_()

    이번에는 Layout 주변의 여백조절과 Layout에 출력되는 요소들의 간격을 조절해보도록 하자. 아래 두 lines의 코드를 통해서 Layout 주변의 여백을 없애고 각 요소들의 간격을 늘려볼수 있다.

            layout1.setContentsMargins(0,0,0,0)
            layout1.setSpacing(20)

     

    3. QGridLayout

    실제로 QVBoxLayout과 QHBoxLayout을 복잡하게 nested Layout으로 구성하기 보다 QGridLayou을 사용하게 되면 각 위젯들은 Grid 형태로 정렬되게 된다. 아래 보여지는 화면과 같이 원하는 위치에 행과 열을 지정하여 위젯을 배치할 수 있다. 또, 지정되지 않은 위치는 아래와 같이 비어있게 된다.

     

    import sys
    
    from PyQt5.QtCore import Qt
    from PyQt5.QtWidgets import (
        QApplication, 
        QMainWindow, 
        QGridLayout,
        QWidget
    )
    
    from layout_colorwidget import Color
    
    class MainWindow(QMainWindow):
        def __init__(self):
            super().__init__()
            self.setWindowTitle("My App")
    
            layout = QGridLayout()
    
            layout.addWidget(Color("red"), 0, 0)
            layout.addWidget(Color("pink"), 1, 0)
            layout.addWidget(Color("blue"), 1, 1)
            layout.addWidget(Color("skyblue"), 2, 1)
    
            widget = QWidget()
            widget.setLayout(layout)
            self.setCentralWidget(widget)
    
    app = QApplication(sys.argv)
    
    window = MainWindow()
    window.show()
    
    app.exec_()

    4. QStackedLayout

    동일 위치에 여러 위젯이 존재하는 화면 구성이다. 포토샵과 같은 그래픽작업 프로그램을 사용해보면 해당 Layout을 이해하기 쉽다. 또는 여러 탭으로 구성되어 화면에서 원하는 탭을 선택하면 선택된 기능이 수행되는 경우를 생각하면 된다. 결론적으로 여러 위젯이 동일 화면 겹쳐 구성 되어있지만 실제로는 단일 위젯만 보여진다. 코드로 구현한 경우 가장 마지막에 추가된 위젯이 보여지게 된다. 이 것을 변경하고 싶다면 .setCurrentIndex() 또는 .setCurrentWidget()으로 보여질 위젯을 선택할 수 있다. 다음 코드는 탭을 구성 후 보여지는 text에 맞게 화면 색을 바꿔주는 코드이다.

     

    import sys
    
    from PyQt5.QtCore import Qt
    from PyQt5.QtWidgets import (
        QApplication, 
        QMainWindow,
        QTabWidget,
        QWidget
    )
    
    from layout_colorwidget import Color
    
    class MainWindow(QMainWindow):
        def __init__(self):
            super().__init__()
            self.setWindowTitle("My App")
    
            tabs = QTabWidget()
            tabs.setTabPosition(QTabWidget.West)
            tabs.setMovable(True)
    
            for n, color in enumerate(["red", "pink", "skyblue", "yellow"]):
                tabs.addTab(Color(color), color)
    
            self.setCentralWidget(tabs)
    
    app = QApplication(sys.argv)
    
    window = MainWindow()
    window.show()
    
    app.exec_()

     

    해당 코드에서는 .setMovable()을 통해서 구성된 탭의 순서 역시 바꿀 수 있다. 

     

    1. Reference book: "Create GUI Applications with Python & Qt5: The hands-on guide to making apps with Python"

     

    반응형
Designed by Tistory.