PyQt 예제 1.6

지난 번에 말했듯이, 이번에는 레이아웃을 변경해볼 것이다. 먼저, 간단히 수직 레이아웃에서 수평 레이아웃으로 변경을 해보겠다.
(KDE 디자인을 변경한 후 찍은 스크린샷이라서 디자인이 많이 바뀌었다...)
-__version__ = "1.5.2"
+__version__ = "1.6.1"
 
 class Form(QDialog):
     def __init__(self, parent=None):
@@ -29,7 +29,7 @@ class Form(QDialog):
         closeButton = QPushButton("닫기(&C)")
         closeButton.setAutoDefault(False)
         
-        layout = QVBoxLayout()
+        layout = QHBoxLayout()
         layout.addWidget(self.label)
         layout.addWidget(self.lineEdit)
         layout.addWidget(self.boldCheckBox)
@@ -38,10 +38,10 @@ class Form(QDialog):
 
         self.connect(self.lineEdit, SIGNAL("returnPressed()"),
                         self.UpdateLabel)
-        self.connect(closeButton, SIGNAL("clicked()"),
-                        self, SLOT("reject()"))
         self.connect(self.boldCheckBox, SIGNAL("stateChanged(int)"),
                         self.LabelBold)
+        self.connect(closeButton, SIGNAL("clicked()"),
+                        self, SLOT("reject()"))
 
         self.setWindowTitle("Main Dialog")
아래 변경은 그냥 코드 위치 변경이므로 볼 필요가 없다. 위에 QVBoxLayout 대신 QHBoxLayout으로 변경된 것만 보면 된다.

이렇게 변경하고 나면 맨 위의 그림처럼 위젯들이 수평으로 배치가 된다.


그러면 임의의 위치에 위젯을 배치하고 싶다면 어떻게 해야 할까? 이것은 QGridLayout을 사용하면 된다.
-__version__ = "1.6.1"
+__version__ = "1.6.2"
 
 class Form(QDialog):
     def __init__(self, parent=None):
@@ -26,20 +26,27 @@ class Form(QDialog):
 
         self.lineEdit = QLineEdit("This is LineEdit Widget")
         self.boldCheckBox = QCheckBox("굵게(&B)")
+        initButton = QPushButton("초기화(&I)")
+        initButton.setAutoDefault(False)
         closeButton = QPushButton("닫기(&C)")
         closeButton.setAutoDefault(False)
         
-        layout = QHBoxLayout()
-        layout.addWidget(self.label)
-        layout.addWidget(self.lineEdit)
-        layout.addWidget(self.boldCheckBox)
-        layout.addWidget(closeButton)
+        buttonLayout = QHBoxLayout()
+        buttonLayout.addWidget(initButton)
+        buttonLayout.addWidget(closeButton)
+
+        layout = QGridLayout()
+        layout.addWidget(self.label, 0, 0, 1, 2)
+        layout.addWidget(self.lineEdit, 1, 0, 1, 2)
+        layout.addWidget(self.boldCheckBox, 2, 0)
+        layout.addLayout(buttonLayout, 3, 0)
         self.setLayout(layout)
 
         self.connect(self.lineEdit, SIGNAL("returnPressed()"),
                         self.UpdateLabel)
         self.connect(self.boldCheckBox, SIGNAL("stateChanged(int)"),
                         self.LabelBold)
+        self.connect(initButton, SIGNAL("clicked()"), self.Initialize)
         self.connect(closeButton, SIGNAL("clicked()"),
                         self, SLOT("reject()"))
 
@@ -54,6 +61,12 @@ class Form(QDialog):
         else:
             self.labelFormat = "{}"
         self.UpdateLabel()
+
+    def Initialize(self):
+        self.labelFormat = "{}"
+        self.boldCheckBox.setCheckState(Qt.Unchecked)
+        self.lineEdit.setText("This is LineEdit Widget")
+        self.label.setText("Hello, PyQt!")
     
 if __name__ == "__main__":
     app = QApplication(sys.argv)
여기에서는 프로그램을 시작한 상태로 리셋 해주는 초기화 버튼을 추가했고, 레이아웃을 두 개 생성했다.

먼저, buttonLayout에는 수평 레이아웃을 생성하여 버튼들을 추가해주었다. 그 아래에 프로그램 전체에 할당될 레이아웃에는 QGridLayout을 생성했다.

이 레이아웃은 원하는 격자 위치에 위젯을 배치할 수 있다(2, 3번째 인자). 그리고 4, 5번째 인자에는 위젯을 늘리고자 하는 크기를 지정할 수 있다. 즉, 레이블 위젯을 배치할 때 행으로 1만큼 늘리고, 열로 2만큼 늘리는 것이다. 그리고 (0, 0) 위치에 레이아웃을 배치한다.

라인 에디터도 마찬가지로 추가하면 된다. 그리고 레이아웃에 레이아웃을 추가할 수가 있다. 즉, layout이 buttonLayout을 품고 있는 것이 된다.

QGridLayout 뿐만 아니라 다른 레이아웃들도 다른 형태 또는 같은 형태의 레이아웃을 추가할 수 있다. 이런 방법으로 다양한 위젯 배치를 쉽게 할 수 있다.

단순히 보면 QGridLayout이 가장 좋은 것처럼 보이지만, 실제로는 그다지 비효율적이다. 모든 것을 다 정해줘야 하기 때문에 약간의 위젯 위치 변경이나 창의 크기 변경이 이루어지면, 이상한 위젯 배치가 생기기 때문이다.

가장 좋은 것은 단순한 레이아웃들을 조합하여 위젯을 배치하는 것이다. 이렇게 하면 코드 상의 위젯 위치만 바꾸어도 깔끔하게 위젯의 순서가 변경된다. 그리고 추가 및 제거가 쉬워진다.

그 아래에 초기화 버튼 추가는 간단한 것이므로 자세한 설명은 생략하겠다.


위에서 소개한 레이아웃 외에도 QFormLayout이 있는데, 이것은 레이블 - 위젯 간의 형식으로 되어 있는 경우에 유용하게 쓸 수 있다.

예를 들어 이름, 나이, 전화번호를 받는 라인 에디터를 생각할 때, 아래와 같이 구성할 수 있을 것이다.

이름: [...]
나이: [...]
전화번호: [...]

왼쪽은 레이블이고, 오른쪽은 라인 에디터이다. 이런 구성을 만들려면 수평, 수직 레이아웃으로는 3개를 써야 할 것이다. (수평 레이아웃에 수직 레이아웃 2개(레이블용, 라인 에디터용)를 배치)

그러나 폼 레이아웃을 쓰면 간단하게 레이블과 라인에디터를 하나로 엮어서 추가할 수 있다.

자세한 것은 레퍼런스를 찾아보면 되고, 이후 프로그램에서도 사용을 했었으므로, 그때 자세히 소개해보겠다.

댓글 없음:

댓글 쓰기