프로그래밍/Python

[python] PyQt5 - 메인 윈도우 생성 후, 실행의 문제점

채윤아빠 2025. 12. 15. 17:01

문제점 및 증상

다음 두 가지 형태로 Qt QWebEngineView를 포함하는 메인 윈도우를 표시하는 방식에 있어서, create_main_window() 함수에서는 QWebEngineView에서 지정된 페이지를 표시하지 못하고 까맣게만 나오는 원인은 무엇일까요?

def create_main_window() -> QApplication:
    app: QApplication = QApplication(sys.argv)

    # 메인 윈도우 생성 및 시작 URL 로딩
    WebMainWindow(
                url=f"http://{SeccDef.UI_HOST}:{SeccDef.UI_PORT}/"
                , logger=main_window_logger
            )

    return app


def run_main_window() -> int:
    app: QApplication = QApplication(sys.argv)

    # 메인 윈도우 생성 및 시작 URL 로딩
    WebMainWindow(
                url=f"http://{SeccDef.UI_HOST}:{SeccDef.UI_PORT}/"
                , logger=main_window_logger
            )

    exit_code = app.exec_()
    return exit_code


if (__name__ == "__main__"):

    # 화면이 정상적으로 표시되지 않음
    app = create_main_window()
    sys.exit( app.exec_() )

    # 화면이 정상적으로 표시됨
    sys.exit( run_main_window() )

원인 분석

create_main_window() 함수 내부에서 WebMainWindow(...)를 호출하여 메인 윈도우 객체를 생성했습니다.
하지만 이 객체를 어떤 변수에도 할당하지 않았습니다. (예: main_window = WebMainWindow(...))

파이썬은 함수 create_main_window()가 실행을 완료하고 app을 반환하는 순간, 이 함수 내에서 생성된 참조되지 않은 지역 객체들(바로 WebMainWindow 인스턴스)을 더 이상 필요 없는 객체로 간주하고 가비지 컬렉터(Garbage Collector, GC)를 통해 메모리에서 해제(소멸자 del 호출)하려고 시도할 수 있습니다.
메인 실행 코드에서 app.exec_()를 호출하는 시점은 이미 create_main_window() 함수가 완전히 종료된 후입니다.
이벤트 루프가 시작될 때는 이미 WebMainWindow 인스턴스가 소멸되었거나, 소멸되는 과정에 있을 가능성이 높습니다.

QWebEngineView는 비동기적으로 페이지를 로드합니다. 윈도우 객체가 소멸되면, 내부의 QWebEngineView 위젯도 소멸되고, 페이지를 로드하는 작업이 시작되기 전에 메모리에서 사라지게 되므로, 아무것도 렌더링하지 못하고 검은색 화면만 남게 됩니다.


해결 방법

가장 손쉬운 해결 방법은 다음과 같이 create_main_window() 함수가 메인 윈도우 객체까지 함께 반환하는 방법입니다.

def create_main_window() -> Tuple[QApplication, WebMainWindow]:
    app: QApplication = QApplication(sys.argv)

    # 메인 윈도우 생성 및 시작 URL 로딩
    main_window = WebMainWindow(
                url=f"http://{SeccDef.UI_HOST}:{SeccDef.UI_PORT}/"
                , logger=main_window_logger
            )

    return (app, main_window)


if (__name__ == "__main__"):

    # 메인 윈도우 객체도 받음
    app, _ = create_main_window()
    sys.exit( app.exec_() )

맺는말

파이썬에서 Qt 윈도우가 검은색으로만 나오는 문제는 대개 이벤트 루프(exec_())가 없거나, 이벤트 루프가 시작되기 전에 윈도우 객체가 가비지 컬렉션으로 소멸되었을 때 발생합니다. 인스턴스를 변수에 명시적으로 할당하여 참조를 유지하는 것이 핵심입니다.



728x90
반응형