PyQt5 Desiginer 활용
계기
프로젝트에서 PyQt를 사용하게 되면서 알게 된 것들을 정리하게 된 것이다. 문제는 한꺼번에 정리하느라 부담이 되고 있다. 필자에게는 익숙한 Tkinter를 사용 안하고 PyQt를 사용하게 된 결정적인 이유는 이러한 툴을 사용하여 생산성을 높일 수 있기 때문이다. PyQt Desiginer 역시 기존 QMaker를 Python에서 사용할 수 있도록 만든 도구이다.
ui 디자이너 툴
활용 방법
기본적으로 desiginer는 xml 포멧으로 *.ui 형태의 파일로 저장이 된다. 이 파일을 python에서 실행하기 위해서는 2가지 방법이 있다.
- *.py 파일로 변환하는 방법.
- 둘째는 ui를 python에서 클래스로 읽어서 인스턴스를 만들는 방법
필자 경험으로는 생산성 측면으로 보면은 사실 두번째 방법이 가장 좋다. 그러나 아직 컴포넌트에 대해서 잘 모르거나 입문 단계에 있을 경우에는 첫번째 방법을 사용하는 것이 학습에는 더 좋은 것으로 생각된다.
디자이너에서 예시 만들기
위지윅스(WYSIWYG)는 마우스로 컴포넌트를 드래그 드랍으로 디자인해서 보이는대로 실행되는 것을 의미한다. 필자 기억으로는 과거 MFC전성기 시절과 비주얼 베이직이 위지윅스로 인기와 욕을 같이 먹었었다는 것으로 알고 있다. 프로젝트로 나가보면 핵심로직은 대부분 코드라서 고객이 별로 딴지는 안걸지만(알면 클라이언트가 직접 코딩?), GUI 같은 눈에 보이는 것은 심할 경우 색상까지 잦은 수정을 요청 하는 경우가 있기 때문에 이런 기능은 빠른 대응이 가능해서 생상성 측면에서 좋은 기능이다.
우선 시작화면서에서 Dialog without buttons 로 생성을 한다음에 새로 생성된 창이 이제 디자인할 창이다. 기본적인 화면 배치는 좌측에 컴포넌트들이 있고, 우측 상단의 Object Inspector는 해당 창의 객들간의 관계를 트리(Tree)구조로 보여준다. 그리고 우측 중단에는 상단 혹은 화면에서 선택된 디자인중인(혹은 선택된) 창의 속성편집창(Property Editor)이 있다.
위젯박스에서 라벨(Label)을 드래그해서 다이얼로그 창에 올린다음에 그리고 객체 트리창에서 다이얼로그를 선택한다음에 상단의 도구메뉴 중에 9개의 작은 박스가 그려진 버튼을 클릭을 한다. 그러면 라벨이 창의 크기에 맞게 늘어나는 것을 확인 할 수 있는데, 이것이 레이아웃 정렬로 수직, 수평, 행렬 이 3가지 방식이 자주 사용된다. GUI 프로그램에서 컴포넌트들을 정렬을 할 수 있는 것은 상당한 이점이다. 만약 이 기능이 없다면, 원래 개발자가 직접 좌표를 동적으로 변동되도록 구현을 해야 한다.
늘어난 TextlLabel을 더블클릭 혹은 선택한 상태에서 속성창의 text 항목을 'Hello World'라고 입력을 한다. 속성창을 본김에 font size도 변경을 해보자. 그리고 잠시 Ctrl + R 키를 눌러서 미리 보기를 한다. 창크기를 변경해보자 창크기에 따라 클자크기도 변경되는 것을 볼 수 있다. 저장을 하면 ui 파일로 저장할 수 있는 것을 확인할 수 있다.
이제 저장을 한다. 저장된 ui 파일이 xml 형식으로 저장된것을 편지기로 열어보면 확인 할 수 있다.
py 파일로 변환하여 실행
윈도우의 경우 cmd 나 powershell 을 열고, 그외는 터미널에서 ui 파일을 저장한 경로로 이동해서 다음과 같은 명령어를 입력한다.
python -m PyQt5.uic.pyuic -x hello.ui -o hello.py
명령어의 의미는 대략 python에서 PyQt5.uic.pyuic 라는 모듈을 hello.ui를 실행해서 hello.py라는 파일로 출력하라는 의미이다. 여기서 출력된 파일은 각각 독자적으로 바로 실행이 가능하다. 출력된 소스 코드를 수정하여 원하는 GUI로 만들어도 된다. 디자이너에서 사용하는 컴포넌트가 어떻게 코드로 작성하는지 궁금하면 이런 방식으로 확인을 해도 괜찮다. 다만, 인스턴스의 속성은 디자이너에서의 속성창과 이름이 대부분 같다.
ui 파일을 클래스로 읽어서 실행
ui 파일을 클래스로 읽는 방법은 PyQt5의 uic 모듈을 사용해서 클래스로 읽는 방식이다.
import sys
from PyQt5.QtWidgets import *
from PyQt5 import uic
ui_helloclass = uic.loadUiType('hello.ui')[0]
class DlgHello(QDialog, ui_helloclass):
def __init__(self):
super().__init__()
self.setupUi(self)
if __name__ == '__main__':
app = QApplication(sys.argv)
dlgHello = DlgHello()
dlgHello.show()
app.exec_()
위의 코드에서 다중상속을 받는데, 그 이유는 py로 컨버팅한 것에서 확인하면 ui로 생성되는 클래스의 자신은 object 인스턴스인데, setupUi() 메서드를 실행하기 위해서는 QtCore나 QtWidgets 혹은 이것이 부모인 인스턴스만 setupUi()메서드에 인자로 넘겨줄 수 있기 때문에 다중으로 한 것이다. 개발자 성향에 따라 이와 조금 다른 스타일로 코딩하는 것이 어느정도 가능하다.
이 방식의 경우 기존의 ui 파일을 수정하지 않고 바로 클래스로 읽어서 상속뒤에 기능을 붙이는 방식이기 때문에 후에 디자이너에서 컴포넌트 객체 명을 바꾸지 않는다면 GUI를 거의 따로 관리할 수 있게 된다. 물론 앞에서 생성된 py 파일도 따로 관리하면 동일한 효과를 볼 수 있지만, 변경될 때마다 변환시켜줘야 한다는 번거로움이 있다.
참고자료
위키독. 파이썬으로 배우는 알고리즘 트레이닝(py변환)
위키독. 파이썬으로 배우는 알고리즘 트레이닝(ui로드)
'Python > PyQt5' 카테고리의 다른 글
[Python, GUI]PyQt5 개요 (0) | 2019.04.19 |
---|