PyQt 예제 1.8.1

예제 1.8 에서는 시그널을 구분하는 방법에 대해 알아보겠다.
 import sys
+from functools import partial
 from PyQt4.QtCore import *
 from PyQt4.QtGui import *

-__version__ = "1.7.1"
+__version__ = "1.8.1"
 
 class Form(QDialog):
     def __init__(self, parent=None):
@@ -55,10 +56,26 @@ class Form(QDialog):
         signal_layout.addWidget(signal_spinBox)
         signal_layout.addStretch()
 
+        connect_partName = QLabel("Connect Test")
+        self.connect_label = QLabel("Button Name")
+        connect_button1 = QPushButton("Button1")
+        connect_button2 = QPushButton("Button2")
+        connect_button3 = QPushButton("Button3")
+
+        connect_layout = QVBoxLayout()
+        connect_layout.addWidget(connect_partName)
+        connect_layout.addWidget(self.connect_label)
+        connect_layout.addWidget(connect_button1)
+        connect_layout.addWidget(connect_button2)
+        connect_layout.addWidget(connect_button3)
+        connect_layout.addStretch()
+
         layout = QHBoxLayout()
         layout.addLayout(simple_layout)
         layout.addSpacing(30)
         layout.addLayout(signal_layout)
+        layout.addSpacing(30)
+        layout.addLayout(connect_layout)
 
         self.setLayout(layout)
 
@@ -67,6 +84,7 @@ class Form(QDialog):
         self.connect(self.simple_boldCheckBox, SIGNAL("stateChanged(int)"),
                         self.Simple_LabelBold)
         self.connect(simple_initButton, SIGNAL("clicked()"), self.Simple_Initialize)
+        
         self.connect(signal_spinBox, SIGNAL("countup(QString)"), 
                         signal_spinCountLabel1, SLOT("setText(QString)"))
         self.connect(signal_spinBox, SIGNAL("countup(QString)"), 
@@ -74,6 +92,13 @@ class Form(QDialog):
         self.connect(signal_spinBox, SIGNAL("countup"), 
                         signal_spinCountLabel3.setText)
 
+        self.connect(connect_button1, SIGNAL("clicked()"),
+                        partial(self.Connect_ButtonClick, "Button1"))
+        self.connect(connect_button2, SIGNAL("clicked()"),
+                        partial(self.Connect_ButtonClick, "Button2"))
+        self.connect(connect_button3, SIGNAL("clicked()"),
+                        partial(self.Connect_ButtonClick, "Button3"))
+
         self.setWindowTitle("Main Dialog")
 
     def Simple_UpdateLabel(self):
@@ -92,6 +117,9 @@ class Form(QDialog):
         self.simple_boldCheckBox.setCheckState(Qt.Unchecked)
         self.simple_lineEidt.setText("This is LineEdit Widget")
         self.simple_label.setText("Hello, PyQt!")
+
+    def Connect_ButtonClick(self, buttonName):
+        self.connect_label.setText(buttonName)
     
 class MySignalSpinBox(QSpinBox):
     changedCount = 0
레이블과 버튼 3개가 추가되었다. 레이블에 버튼 이름을 표시해줄 것이다. 그러면 이 버튼들을 구분할 수 있어야 한다.

간단하지만 좀 무식(?)한 방법은 버튼마다 메소드를 따로 구현해서 연결해주는 것이다. 방법이야 간단하지만 코드가 몇 단어를 빼고 중복되기 때문에 매우 비효율적인 작업일 수 밖에 없다.

따라서 시그널을 구분할 수 있다면, 간단하게 해결할 수 있을 것이다.

방법으로는 3가지가 있는데, 이번 글에서는 partial 함수를 사용해서 구분하는 방법을 소개하겠다.

functools 모듈에 partial 함수가 있는데, 이 함수는 함수와 인자를 받아서 그것을 하나로 묶어서 다른 하나의 함수처럼 행동을 한다.

즉, 레이블에 버튼 명을 표시해주는 메소드를 구현한 후, 버튼 명을 이 메소드에 넘겨주는 방법을 사용하는 것이다.

먼저, 레이블에 버튼 이름을 표시해주는 메소드는 Connect_ButtonClick 메소드이다. 이 메소드는 인자로 buttonName 을 받고 있다.

버튼의 connect 쪽 코드를 보면, 버튼을 클릭 했을 때, partial 함수를 호출하도록 되어 있다. 그리고 partial 함수는 Connect_ButtonClick 메소드와 버튼 이름을 인자로 받고 있다.

이렇게 connect를 해주면 partial 함수가 호출되고, partial 은 Connect_ButtonClick 메소드를 버튼 이름과 함께 호출하게 되므로, 메소드 하나만 구현하고도 시그널을 구분할 수 있게 된다.

참고로 이 partial 방법은 PyQt 4.3 이상에서만 가능하다. 이전 버전에서는 partial 함수를 connect 메소드에 직접 넣어주게 되면, 코드 실행 후 partial 함수가 실행 영역을 벗어나게 되어 쓰레기 수집 되기 때문이다.

따라서 connect 가 호출할 메소드가 없어져서 문제가 발생하는 것이다. 하지만 4.3 이후부터는 이를 특별하게 처리하고 있기 때문에 이러한 문제가 없어졌다.

만약, 4.3 이전에서 사용을 하고 싶다면 partial 함수를 따로 떼낸 후, 변수에 할당하고 그 변수를 connect 의 슬롯에 쓰면 된다.

댓글 없음:

댓글 쓰기