PyQt QtDesigner

1. QtDesigner 소개

지금까지 GUI 프로그램의 기본 개념들을 이해하기 위해 파이썬 코드를 사용하여 UI 요소들을 생성하고 사용하였다. 하지만, 복잡한 UI 인 경우 혹은 UI 작업이 많은 경우, 일일이 UI 요소를 코드에서 생성하는 것은 효율적이지 않다. 이러한 단점을 극복하기 위해 PyQt 안에는 QtDesigner라는 Qt UI Designer 도구가 포함되어 있다. QtDesigner는 UI 위젯들을 드래그-앤-드랍으로 배치할 수 있으며, 각 위젯들의 속성을 쉽게 설정할 수 있다. 이러한 UI 디자인 작업은 .ui 파일(XML 포맷 파일)로 일단 저장되고, PyQt의 Converter를 사용하여 .py 파일로 변환할 수 있다.

2. QtDesigner 실행

QtDesigner 실행파일은 PyQt가 설치된 디렉토리에 있는데, 예를 들어 윈도우즈의 경우 C:\Python34\Lib\site-packages\PyQt4\designer.exe 와 같은 경로를 갖는다 (파이썬이 C:\Python34에 설치된 경우). (윈도우즈의 경우 시작버튼을 누르고 검색에서 Designer를 찾으면 쉽게 찾을 수 있다). QtDesigner가 실행되면 아래와 같이 새로운 폼을 만들도록 화면이 나오는데, 여기서 메인윈도우 폼 혹은 다이얼로그 폼 등을 선택할 수 있다.

3. QtDesigner UI 작업

QtDesigner는 크게 세 영역으로 나누어져 있는데, 왼쪽에 여러 위젯들을 모아 놓은 도구상자인 Widget Box가 있고, 중앙에는 WYSIWYG으로 폼(Form)을 조작하는 화면이 있으며, 오른쪽에는 (1)폼 상에 있는 객체들을 트리 구조로 표시한 Object Inspector (2) 각 위젯의 속성들을 설정하는 Property Editor (3) 이벤트(Signal)와 관련 핸들러(Slot)를 표시한 Signal/Slot Editor (그리고 기타 QAction을 편집할 수 있는 Action Editor, 리소스를 관리할 수 있는 Resource Browser)가 있다.

QtDesigner에서의 UI 작업은 Widget Box에서 필요한 위젯 컨트롤을 끌어다 중앙의 폼에 옮겨 놓으면서 하게 된다. 위젯들은 드래그-앤-드랍한 위치에 놓이게 되는데, 필요하면 상단 툴바에 있는 레이아웃 버튼을 눌러 해당 레이아웃에 맞게 자동 조절되게 할 수도 있다. 그리고 꼭 필요한 것은 아니지만, 일반적으로 각 위젯에 대해 필요한 속성을 Property Editor에서 새로 지정해 주게 된다. 특히, 위젯의 objectName 속성은 향후 파이쎤 코드에서 사용될 수 있으므로 의미있게 지정해 주는 것이 좋다. 아래는 간단하게 QLabel, QLineEdit, QPushButton 컨트롤을 드래그-앤-드랍하여 만들어 본 화면이다. 참고로 QtDesigner에서 Form - Preview 메뉴를 선택하면 실행시의 폼 화면을 미리 볼 수 있다.

4. UI 파이썬 파일 생성

QtDesigner으로 UI 작업이 모두 끝났으면, File - Save 를 눌러 저장한다. 이때 결과물은 .ui 파일로 저장되는데, 이 .ui 파일은 UI 작업 내용을 XML 형태로 저장한 것이다. 이렇게 저장된 .ui 파일은 다음과 같이 pyuic4 라는 명령을 통해 파이썬 .py 파일로 변환된다. pyuic4은 QtDesigner가 있는 디렉토리와 같은 디렉토리에 있다.

C> pyuic4 ".ui파일명" -o ".py파일명"

5. UI 파이썬 파일 사용

위와 같이 생성된 .py 파일은 UI Form (메인윈도우 혹은 다이얼로그) 에 대한 클래스를 담고 있으며, 그 클래스 안에 각 위젯에 대한 인스턴스 변수를 제공하고 있다. 파이썬 프로그램에서 이 UI 폼 클래스의 객체를 생성해서 폼을 화면에 표시하게 되고, 각 위젯들을 엑세스하여 값을 읽고 쓰는 일, 그리고 각 위젯에 대해 이벤트핸들러를 추가하는 일이 가능하다. 먼저 아래 예제는 QtDesigner로 생성한 UI 다이얼로그를 화면에 보여주는 코드이다. 이 코드는 다이얼로그를 화면에 보여주지만, 버튼을 클릭하는 등의 이벤트핸들링을 아직 없는 상태이다.

from PyQt4.QtGui import *
import sys

# MyDiag.py 모듈 import
import MyDiag

# MyDiag 모듈 안의 Ui_MyDialog 클래스로부터 파생
class XDialog(QDialog, MyDiag.Ui_MyDialog):
    def __init__(self):
        QDialog.__init__(self)
		# setupUi() 메서드는 화면에 다이얼로그 보여줌
        self.setupUi(self)

app = QApplication(sys.argv)
dlg = XDialog()
dlg.show()
app.exec_()

먼저 QtDesigner로부터 생성된 파이썬 UI 파일이 MyDiag.py라고 가정하고, 이 모듈을 위 코드가 있는 폴더에 복사한 후, MyDiag.py를 import를 사용해서 로드한다. MyDiag.py 안에 있는 다이얼로그 클래스의 이름을 살펴보면 Ui_MyDialog 이므로, 파생클래스 XDialog를 만들 때, 이 MyDiag.Ui_MyDialog 클래스를 QDialog와 함께 베이스클래스에 넣는다 (주: 파이썬은 Multiple Inheritance가 가능하다).
그리고, XDialog 클래스의 생성자에서 MyDialog를 화면에 표시하기 위해 Ui_MyDialog클래스 안에 있는 setupUi() 메서드를 호출하면 된다.

6. UI 핸들링을 파이썬 코드

UI 폼을 실제 핸들링하는 일은 파이썬 코드로 작성해 준다. 즉, UI 요소들의 값을 읽거나 변경하는 일, 혹은 버튼 등의 컨트롤에 대해 이벤트 핸들러를 추가하는 일 등은 파이썬 코드에서 추가해 준다. 아래 예제를 보면, [저장] 버튼이 클릭되었을 때 saveData() 라는 메서드를 실행하고, [취소] 버튼이 클릭되었을 때 clearData() 라는 메서드를 실행하게 된다.

from PyQt4.QtGui import *
import MyDiag
import sys

class XDialog(QDialog, MyDiag.Ui_MyDialog):
    def __init__(self):
        QDialog.__init__(self)
        self.setupUi(self)

		# 버튼 이벤트 핸들러
        self.btnSave.clicked.connect(self.saveData)
        self.btnCancel.clicked.connect(self.clearData)

	# 저장 버튼 클릭시
    def saveData(self):
        with open("data.csv", "a", encoding="utf-8") as f:
            s = "%s,%s,%s\n" % (self.editName.text(),
                                self.editCompany.text(),
                                self.editAddr.text())
            f.write(s)
        QMessageBox.information(self, "저장", "성공적으로 저장")

	# 취소 버튼 클릭시
    def clearData(self):
        self.editName.clear()
        self.editCompany.clear()
        self.editAddr.clear()

app = QApplication(sys.argv)
dlg = XDialog()
dlg.show()
app.exec_()

저장 버튼 이벤트 핸들러 saveData()에서는 self.editName.text() 와 같이 각 텍스트 위젯으로부터 입력 텍스트를 읽어 데이타 파일에 저장하고 메시지박스를 띄워 표시해 준다. 여기서 데이타 파일은 UTF-8 인코딩을 사용하도록 정의하여 한글OS가 아닌 곳에서도 한글이 깨지지 않게 하였다.
또한 취소 버튼이 클릭되면, 모든 텍스트 위젯들의 값을 지우는 코드를 추가하였다.

본 웹사이트는 광고를 포함하고 있습니다. 광고 클릭에서 발생하는 수익금은 모두 웹사이트 서버의 유지 및 관리, 그리고 기술 콘텐츠 향상을 위해 쓰여집니다.