5.10. 애드온 GUI(그래픽 사용자 인터페이스)에 대한 지원 추가


다음 고급 단계를 수행하여 애드온의 그래픽 사용자 인터페이스(GUI)에 지원을 추가할 수 있습니다.

  1. Normalspoke 클래스에 필요한 속성 정의
  2. __init__초기화 방법 정의
  3. 새로 고침 정의,적용실행 방법
  4. 상태준비된,완료필수 속성 정의

사전 요구 사항

  • 추가 기능에는 Kickstart에 대한 지원이 포함되어 있습니다. Anaconda 애드온 구조를 참조하십시오.
  • SpokeWindow 와 같은 Anaconda 에 대한 Gtk 위젯을 포함하는 anaconda-widgets 및 anaconda-widgets-devel 패키지를 설치합니다.

프로세스

  • 다음 예에 따라 모든 필수 정의로 다음 모듈을 생성하여 애드온 GUI(그래픽 사용자 인터페이스)에 대한 지원을 추가합니다.

    # will never be translated
    _ = lambda x: x
    N_ = lambda x: x
    
    # the path to addons is in sys.path so we can import things from org_fedora_hello_world
    from org_fedora_hello_world.gui.categories.hello_world import HelloWorldCategory
    from pyanaconda.ui.gui.spokes import NormalSpoke
    
    # export only the spoke, no helper functions, classes or constants
    all = ["HelloWorldSpoke"]
    
    class HelloWorldSpoke(FirstbootSpokeMixIn, NormalSpoke):
        """
        Class for the Hello world spoke. This spoke will be in the Hello world
        category and thus on the Summary hub. It is a very simple example of a unit
        for the Anaconda's graphical user interface. Since it is also inherited form
        the FirstbootSpokeMixIn, it will also appear in the Initial Setup (successor
        of the Firstboot tool).
    
        :see: pyanaconda.ui.common.UIObject
        :see: pyanaconda.ui.common.Spoke
        :see: pyanaconda.ui.gui.GUIObject
        :see: pyanaconda.ui.common.FirstbootSpokeMixIn
        :see: pyanaconda.ui.gui.spokes.NormalSpoke
    
        """
    
        # class attributes defined by API #
    
        # list all top-level objects from the .glade file that should be exposed
        # to the spoke or leave empty to extract everything
        builderObjects = ["helloWorldSpokeWindow", "buttonImage"]
    
        # the name of the main window widget
        mainWidgetName = "helloWorldSpokeWindow"
    
        # name of the .glade file in the same directory as this source
        uiFile = "hello_world.glade"
    
        # category this spoke belongs to
        category = HelloWorldCategory
    
        # spoke icon (will be displayed on the hub)
        # preferred are the -symbolic icons as these are used in Anaconda's spokes
        icon = "face-cool-symbolic"
    
        # title of the spoke (will be displayed on the hub)
        title = N_("_HELLO WORLD")
    Copy to Clipboard Toggle word wrap

    __all__ 특성은 spoke 클래스를 내보낸 다음 GUI 애드온 기본 기능에 언급된 속성 정의를 포함하여 정의의 첫 번째 행을 내보냅니다. 이러한 속성 값은 com_example_hello_world/gui/spokes/hello.glade 파일에 정의된 위젯을 참조합니다. 두 가지 다른 주요 속성이 있습니다.

  • category 에서는 com_example_hello_world.gui.categories 모듈에서 HelloWorldCategory 클래스에서 가져온 값이 있습니다. 추가 기능 경로가 sys.path 에 있는 HelloWorldCategorycom_example_hello_world 패키지에서 값을 가져올 수 있도록 합니다. category 속성은 변환을 위해 문자열을 표시하는 N_ 함수 이름의 일부이지만 이후 단계에서 변환이 이루어지므로 문자열의 번역되지 않은 버전을 반환합니다.
  • 정의에 하나의 밑줄을 포함하는 제목 입니다. 제목 특성 밑줄은 제목 자체의 시작을 표시하고 Alt+H 키보드 바로 가기를 사용하여 대화에 연결할 수 있도록 합니다.

    일반적으로 클래스 정의의 헤더와 클래스 특성 정의는 클래스의 인스턴스를 초기화하는 생성자입니다. Anaconda 그래픽 인터페이스 오브젝트의 경우 새 인스턴스를 초기화하는 두 가지 방법인 __init__ 메서드와 initialize 방법이 있습니다.

    이러한 두 함수 뒤에 있는 이유는 GUI 개체가 한 번에 메모리에 생성되고 다른 시간에 완전히 초기화 수 있기 때문입니다. 따라서 __init__ 메서드는 부모의 __init__ 메서드만 호출하고, 예를 들어 비GUI 속성을 초기화해야 합니다. 반면 설치 프로그램의 그래픽 사용자 인터페이스가 초기화될 때 호출되는 initialize 메서드는 대화 상자의 전체 초기화를 완료해야 합니다.

    Hello World 애드온 예제에서 다음과 같이 이 두 메서드를 정의합니다. __init__ 메서드에 전달된 인수의 수 및 설명을 확인합니다. 예를 들면 다음과 같습니다.

    def __init__(self, data, storage, payload):
        """
        :see: pyanaconda.ui.common.Spoke.init
        :param data: data object passed to every spoke to load/store data
        from/to it
        :type data: pykickstart.base.BaseHandler
        :param storage: object storing storage-related information
        (disks, partitioning, boot loader, etc.)
        :type storage: blivet.Blivet
        :param payload: object storing packaging-related information
        :type payload: pyanaconda.packaging.Payload
    
        """
    
        NormalSpoke.init(self, data, storage, payload)
        self._hello_world_module = HELLO_WORLD.get_proxy()
    
    def initialize(self):
        """
        The initialize method that is called after the instance is created.
        The difference between init and this method is that this may take
        a long time and thus could be called in a separate thread.
        :see: pyanaconda.ui.common.UIObject.initialize
        """
        NormalSpoke.initialize(self)
        self._entry = self.builder.get_object("textLines")
        self._reverse = self.builder.get_object("reverseCheckButton")
    Copy to Clipboard Toggle word wrap

    __init__ 메서드에 전달된 data 매개변수는 모든 데이터가 저장된 Kickstart 파일의 in-memory 트리와 같습니다. ancestors' __init__ 메서드 중 하나에서 self.data 특성에 저장되므로 클래스의 다른 모든 메서드는 구조를 읽고 수정할 수 있습니다.

    참고

    RHEL10부터는 스토리지 오브젝트 를 더 이상 사용할 수 없습니다. 애드온이 스토리지 구성과 상호 작용해야 하는 경우 Storage DBus 모듈을 사용합니다.

    Hello World 애드온 예제에 HelloWorldData 클래스가 이미 정의되어 있으므로 이 애드온 에 대한 self.data에 있는 하위 트리가 이미 있습니다. 클래스의 인스턴스인 루트는 self.data.addons.com_example_hello_world 로 사용할 수 있습니다.

    ancestor의 __init__ 이 수행하는 또 다른 작업은 원래의 .glade 파일을 사용하여 GtkBuilder 인스턴스를 초기화하고 self.builder 로 저장하는 것입니다. initialize 메서드는 이를 사용하여 Kickstart 파일의 %addon 섹션에서 텍스트를 표시하고 수정하는 데 사용되는 Gtk CryostatEntry 를 가져옵니다.

    __init__initialize 메서드는 모두 spoke가 생성될 때 중요합니다. 그러나 spoke의 주요 역할은 spoke의 값을 변경하거나 설정하려는 사용자가 방문하는 것입니다. 이를 활성화하려면 세 가지 다른 방법을 사용할 수 있습니다.

  • 새로 고침 - 스포크가 방문하려고 할 때 호출됩니다. 이 방법은 주로 UI 요소의 상태를 새로 고침하여 표시된 데이터가 내부 데이터 구조와 일치하도록 하고, 이를 통해 self.data 구조에 저장된 현재 값이 표시되도록 합니다.
  • apply - spoke가 남아 있을 때 호출되고 UI 요소의 값을 self.data 구조에 다시 저장하는 데 사용됩니다.
  • execute - 사용자가 스포크를 나가서 발표자의 새로운 상태에 따라 런타임 변경을 수행하는 데 사용될 때 호출됩니다.

    이러한 함수는 샘플 Hello World 애드온에서 다음과 같은 방식으로 구현됩니다.

    def refresh(self):
        """
        The refresh method that is called every time the spoke is displayed.
        It should update the UI elements according to the contents of
        internal data structures.
        :see: pyanaconda.ui.common.UIObject.refresh
        """
        lines = self._hello_world_module.Lines
        self._entry.get_buffer().set_text("".join(lines))
        reverse = self._hello_world_module.Reverse
        self._reverse.set_active(reverse)
    
    def apply(self):
        """
        The apply method that is called when user leaves the spoke. It should
        update the D-Bus service with values set in the GUI elements.
        """
        buf = self._entry.get_buffer()
        text = buf.get_text(buf.get_start_iter(),
                            buf.get_end_iter(),
                            True)
        lines = text.splitlines(True)
        self._hello_world_module.SetLines(lines)
    
        self._hello_world_module.SetReverse(self._reverse.get_active())
    
    def execute(self):
      """
      The execute method that is called when the spoke is exited. It is
      supposed to do all changes to the runtime environment according to
      the values set in the GUI elements.
    
      """
    
      # nothing to do here
      pass
    Copy to Clipboard Toggle word wrap

    몇 가지 추가 방법을 사용하여 spoke의 상태를 제어할 수 있습니다.

  • Ready - 스포크가 방문할 준비가 되었는지 여부를 결정합니다. 값이 "False"인 경우, 예를 들어 패키지 소스가 구성되기 전에 Package Selection spoke 에 액세스할 수 없습니다.
  • completed - spoke가 완료되었는지 확인합니다.
  • 필수 - spoke가 필수인지 아닌지를 결정합니다. 예를 들어 자동 파티셔닝을 사용하려는 경우에도 항상 방문해야 하는 Installation Destination spoke가 필요합니다.

    이러한 모든 속성은 설치 프로세스의 현재 상태에 따라 동적으로 결정되어야 합니다. 다음은 Hello World 애드온에서 이러한 메서드의 샘플 구현이며, HelloWorldData 클래스의 텍스트 속성에 특정 값을 설정해야 합니다.

    @property
    def ready(self):
        """
        The ready property reports whether the spoke is ready, that is, can be visited
        or not. The spoke is made (in)sensitive based on the returned value of the ready
        property.
    
        :rtype: bool
    
        """
    
        # this spoke is always ready
        return True
    
    
    @property
    def mandatory(self):
        """
        The mandatory property that tells whether the spoke is mandatory to be
        completed to continue in the installation process.
    
        :rtype: bool
    
        """
    
        # this is an optional spoke that is not mandatory to be completed
        return False
    Copy to Clipboard Toggle word wrap

    이러한 속성이 정의되면 spoke는 해당 접근성과 완전성을 제어할 수 있지만 내부에 구성된 값에 대한 요약을 제공할 수 없습니다. 원하는 대로 구성 방법을 보려면 spoke를 방문해야 합니다. 따라서 status 라는 추가 속성이 있습니다. 이 속성에는 구성된 값에 대한 간략한 요약이 포함된 한 줄의 텍스트가 포함되어 있으며, 이 항목은 대화 상자 아래에 표시됩니다.

    status 속성은 다음과 같이 Hello World 예제 애드온에 정의됩니다.

    @property
    def status(self):
        """
        The status property that is a brief string describing the state of the
        spoke. It should describe whether all values are set and if possible
        also the values themselves. The returned value will appear on the hub
        below the spoke's title.
        :rtype: str
        """
        lines = self._hello_world_module.Lines
        if not lines:
            return _("No text added")
        elif self._hello_world_module.Reverse:
            return _("Text set with {} lines to reverse").format(len(lines))
        else:
            return _("Text set with {} lines").format(len(lines))
    Copy to Clipboard Toggle word wrap

    예제에서 설명하는 모든 속성을 정의하면 애드온에서 GUI(그래픽 사용자 인터페이스)와 Kickstart를 표시하는 완전한 지원이 제공됩니다.

    참고

    여기에 설명된 예제는 매우 간단하며 모든 제어 기능이 포함되어 있지 않습니다. Python Gtk 프로그래밍에 대한 지식이 GUI에서 기능적이고 상호 작용하는 대화 방식을 개발하는 데 필요합니다.

    주목할 만한 제한은 각 스포크 Window 위젯의 인스턴스인 자체 기본 창이 있어야 한다는 것입니다. Anaconda와 관련된 다른 위젯과 함께 이 위젯은 anaconda-widgets 패키지에 있습니다. Glade 정의와 같은 GUI 지원을 통한 애드온 개발에 필요한 다른 파일은 anaconda-widgets-devel 패키지에서 찾을 수 있습니다.

    그래픽 인터페이스 지원 모듈에 필요한 모든 방법이 포함된 경우 다음 섹션을 계속 사용하여 텍스트 기반 사용자 인터페이스에 대한 지원을 추가할 수 있습니다.

맨 위로 이동
Red Hat logoGithubredditYoutubeTwitter

자세한 정보

평가판, 구매 및 판매

커뮤니티

Red Hat 문서 정보

Red Hat을 사용하는 고객은 신뢰할 수 있는 콘텐츠가 포함된 제품과 서비스를 통해 혁신하고 목표를 달성할 수 있습니다. 최신 업데이트를 확인하세요.

보다 포괄적 수용을 위한 오픈 소스 용어 교체

Red Hat은 코드, 문서, 웹 속성에서 문제가 있는 언어를 교체하기 위해 최선을 다하고 있습니다. 자세한 내용은 다음을 참조하세요.Red Hat 블로그.

Red Hat 소개

Red Hat은 기업이 핵심 데이터 센터에서 네트워크 에지에 이르기까지 플랫폼과 환경 전반에서 더 쉽게 작업할 수 있도록 강화된 솔루션을 제공합니다.

Theme

© 2025 Red Hat