본문 바로가기
프로그래밍/Python

Pyinstaller에서 PyQt .ui 파일을 포함해 빌드해야 할 때

by 페이지다운 2020. 4. 12.
반응형

지난번 글에서 인터파크 티켓팅 매크로 코드를 공개했는데, 보면 프로그램의 기능을 담당하는 .py 스크립트와 UI를 담당하는 .ui 파일이 분리되어 있는 것을 알 수 있다.

 

나는 보통 pyuic를 통해 .ui 파일에서 .py로 스크립트를 변경해 썼다. 

 

이 방법이 여러모로 편리하지만, 원치 않는 찌거기같은 코드가 마구 딸려와서 코드가 지저분해지는 경향이 있었고, UI의 변경이 어려웠다. 난 코드로 UI 디자인을 거의 못하기 때문에 Qt Designer을 쓰는데, 그런 나에겐 최악의 상황이다.

 

따라서 uic.loadUiType을 통해 ui를 따로 로드해서 프로그램을 만들어 보기로 했고 이 티켓팅 매크로가 그 첫 시도의 결과물이다.

 

ui를 따로 로드했을 때의 단점은 텍스트 에디터에서 보조를 받기 쉽지 않다는 점과, pyinstaller로 빌드 시 파일을 포함해서 빌드하지 않는다는 점이다. 따라서 .py 스크립트만 빌드하면 반드시 ui 파일이 따라다녀야 한다. 코드 공개를 원치 않는 사람들이나 파일을 하나로 깔끔하게 합치고 싶은 사람들에게는 여러모로 불편한 점이다.

 

그래서 방법을 알아보다가 찾아서 공유한다.

 

일단 기본적으로 아래 코드를 최상단에 추가한다. 

1
2
3
4
5
6
7
import sys
import os
 
def resource_path(relative_path):
    """ Get absolute path to resource, works for dev and for PyInstaller """
    base_path = getattr(sys, '_MEIPASS', os.path.dirname(os.path.abspath(__file__)))
    return os.path.join(base_path, relative_path)
cs

stack overflow에서 구한 코드다. 정확히 무슨 역할을 하는지는 모르겠지만 아마도 바이너리 파일 내의 파일을 일반적인 파일처럼 열 수 있도록 해주는 코드 같다.

 

그러고 나서는 이제 pyinstaller에게 ui파일을 포함하도록 알려 줘야 하는데, spec 파일이 그것이다. spec 파일은 프로그램 빌드 시 다양한 옵션을 줄 수 있도록 하는 파일이다. 먼저 .py 스크립트만 빌드를 하면 spec 파일이 자동으로 생성된다. 그러면 그걸 수정하고 다시 빌드하면 된다.

 

우리는 ui 파일만 포함시키면 되므로, 아래와 같이 해주면 된다

1
2
3
4
a = Analysis(
    datas=[ ('TicketingMacro.ui', '.') ],
    ...
    )
cs

그러고 난 후 다시 원래 .py 스크립트로 돌아가서

1
2
3
form = resource_path('TicketingMacro.ui')
 
form_class = uic.loadUiType(form)[0
cs

위와 같이 resource_path 함수 안에 .ui파일을 적어 주고 반환값을 uic.loadUiType에다가 넘겨 주면 된다.

반응형

댓글