본문 바로가기
목차
Python/PySide PyQt

[PyQt] ui 파일에서 동적으로 python class 생성: uic.loadUiType

by ds31x 2024. 5. 12.
728x90
반응형

uic.loadUiType :

PyQt에서 uic.loadUiType 함수는 Qt Designer .ui 파일에서 Python 코드를 생성하는 기능을 제공.

 

참고로 Qt 에서는 이 방식보다
가능하면, uic로 정적으로 python code를 생성하고
이를 import하는 방식을 권함.

 

이 함수는

  • 사용자 인터페이스 파일(.uic 파일)을 파이썬 클래스로 동적으로 변환하여 반환함으로써,
  • 해당 클래스 타입을 동적으로 로드하고 사용할 수 있게 해줌.

loadUiType 과 loadUi :

비슷한 방법으로 uic 모듈은 loadUi 함수를 제공함.

  • loadUiuic 파일(첫번째 argument로 지정)을 직접 widget 객체 (두번째 arguement로 지정)에 로드하여 즉시 사용 가능한 인스턴스를 생성하는 간단한 방식임.
  • loadUiTypeuic파일에서 ui_form_class(폼 클래스)와 ui_base_class(기본 위젯 클래스)를 tuple로 반환하여 사용자가 이를 상속받아 확장 가능한 클래스를 정의할 수 있게 해주는 더 유연한 방식임.

일반적으로 작은 프로젝트나 빠른 개발에는 loadUi를, 더 구조화된 대규모 애플리케이션에는 loadUiType을 선호함.


QUiLoader :

참고로 uic 모듈을 이용하는 이같은 방식들은 PyQt에서만 제공하기 때문에,
PySide에서도 같이 사용가능한 QUiLoader를 이용한 방식을 개인적으로 권함.

2024.05.06 - [Python/PySide PyQt] - [PySide6] QtUiTools.QUiLoader 를 Qt Designer의 .ui 사용하기.

 

[PySide6] QUiLoader 를 Qt Designer의 .ui 사용하기.

QUiLoaderQUiLoader는 Qt 프레임워크에서 Qt Designer 로 생성된 .ui 파일을 runtime(런타임)에서 로딩하여 widget으로 생성하는 역할을 수행함. .ui 파일들은 Qt Designer라는 도구를 사용하여 XML 형식으로 만들어

ds31x.tistory.com


반환값 :

uic.loadUiType 함수를 사용할 때 반환되는 ui_form_classui_base_class는 PyQt에서 UI 파일을 파이썬 코드로 변환할 때 생성되는 두 가지 유형의 클래스이며 다음과 같은 차이점을 가짐:


ui_form_class

  • 정의:
    • ui_form_classui_base_class를 상속받는 또 다른 클래스이며,
    • UI 파일에서 정의된 실제 인터페이스 구성요소들을 초기화하고 설정하는 메서드(setupUi)를 포함하고 있음.
  • 역할:
    • 이 클래스의 주된 기능은 setupUi 메소드를 통해
    • UI 파일에서 정의된 위젯들을 실제로 초기화하고,
    • 이벤트 핸들러(신호 및 슬롯 연결)와 같은 추가적인 설정을 수행가능하도록 해 줌(inheritance를 이용하여).
  • 사용:
    • 일반적으로 사용자는 이 클래스를 상속받아 새로운 클래스를 정의하고,
    • 생성자에서 이 클래스의 instance method인 setupUi 메소드를 호출하여 UI 구성요소를 초기화함.
    • 사용자는 이 클래스를 확장하여 추가 기능이나 이벤트 핸들러를 구현할 수 있음.
    • .ui 파일 내의 widget클래스의 name 속성으로 접근하여 코드 작성.

ui_base_class

  • 정의:
    • ui_base_class는 UI 파일에서 정의된 위젯들의 컨테이너 역할을 하는 base class(기본 클래스)임.
    • 일반적으로 QWidget, QDialog, QMainWindow 등의 PyQt 위젯 클래스 중 하나에서 파생됨.
  • 역할:
    • 이 클래스는 .ui 파일에 정의된 위젯들을 포함하고 있는 기본적인 프레임을 제공함.
    • 직접적인 UI 로직이나 사용자 정의 코드는 포함하지 않음.
  • 사용:
    • 대부분의 경우 직접적으로 이 클래스를 사용하지는 않음 (상속받아서 사용함).
    • 대신 이 클래스는 앞서의 Form Class와 함께 사용되어 UI를 구성하는 기본적인 위젯들을 제공함.

즉, ui_base_class는 기본적인 위젯 컨테이너 역할을 하며,ui_form_class는 이 위젯들을 초기화(setupUI 메서드 제공)하고 추가 설정을 제공하는 구체적인 기능을 담당함.


사용방식 :

uic.loadUiType 함수의 사용 예제는 다음과 같음:

from PyQt6 import uic  

ui_form_class, ui_base_class = uic.loadUiType("path_to_your_ui_file.ui")  

class MyWindow(ui_base_class, ui_form_class):  
    def __init__(self):  
        super().__init__()  
        self.setupUi(self)  

# 이제 MyWindow 클래스는 UI 파일의 위젯과 메소드에 직접 접근할 수 있습니다.
  • 이 코드에서 uic.loadUiType는 지정된 .ui 파일을 분석하고, 해당 UI의 구조를 기반으로 두 개의 클래스를 반환.
    • ui_base_class: UI 파일에서 지정된 베이스 클래스 (QMainWindow, QDialog, QWidget 등)
    • ui_form_class: setupUi 메서드를 포함한 UI 클래스
  • MyWindow 클래스는 이 두 클래스를 상속받아 생성자에서 setupUi 메소드를 호출함으로써 UI를 초기화.
  • 이후 .ui 파일 내의 widget클래스의 name 속성으로 접근하여 코드 작성.

만약 QMainWindow를 상속해야 하는 경우엔 다음과 같이 처리한다 (단, Designer에서 form 중 Main Window 템플릿을 선택하여 uic 파일을 만든 경우에만 사용하는 것을 추천하고, 가급적 ui파일의 base class를 사용할 것).

from PyQt6 import QtWidgets, uic
from PyQt6.QtWidgets import QApplication

ui_form_class, ui_base_class = uic.loadUiType("path_to_your_ui_file.ui")

class MyApplication(QtWidgets.QMainWindow, ui_form_class):
    def __init__(self, parent=None):
        super().__init__(parent)
        self.setupUi(self)  # ui_form_class의 setupUi를 호출하여 UI 초기화

if __name__ == "__main__":
    import sys
    app = QApplication(sys.argv)
    window = MyApplication()
    window.show()
    sys.exit(app.exec())

 

위와 같이, 간단한 구현에서는 ui파일의 base class (위의 예제에서 ui_base_class)가 아닌 다른 컨테이너 class를 사용해도 되지만 다음의 문제가 발생할 수 있으니 가급적 ui_base_class 를 상속하는게 좋다.

 

  • 레이아웃 문제: Dialog용 UI를 QMainWindow에서 사용하면 레이아웃이 깨질 수 있음
  • 고유 기능 누락: Main Window용 UI를 QWidget에서 사용시 QMainWindowmenuBar(), statusBar() 등이 제대로 작동하지 않을 수 있음
  • 시그널/슬롯 문제: 특정 클래스의 시그널이 제대로 연결되지 않을 수 있음

 

 

728x90