Maxon Developers Maxon Developers
    • Documentation
      • Cinema 4D Python API
      • Cinema 4D C++ API
      • Cineware API
      • ZBrush Python API
      • ZBrush GoZ API
      • Code Examples on Github
    • Forum
    • Downloads
    • Support
      • Support Procedures
      • Registered Developer Program
      • Plugin IDs
      • Contact Us
    • Categories
      • Overview
      • News & Information
      • Cinema 4D SDK Support
      • Cineware SDK Support
      • ZBrush 4D SDK Support
      • Bugs
      • General Talk
    • Unread
    • Recent
    • Tags
    • Users
    • Login

    How to Get checked/unchecked state of menu item?

    Cinema 4D SDK
    s22 python
    2
    3
    581
    Loading More Posts
    • Oldest to Newest
    • Newest to Oldest
    • Most Votes
    Reply
    • Reply as topic
    Log in to reply
    This topic has been deleted. Only users with topic management privileges can see it.
    • chuanzhenC
      chuanzhen
      last edited by

      Hi,
      Use MenuInitString() change checked/unchecked state of menu item,
      how to get checked/unchecked state?
      Thanks for any help!

      相信我,可以的!

      ferdinandF 1 Reply Last reply Reply Quote 0
      • ferdinandF
        ferdinand @chuanzhen
        last edited by ferdinand

        Hello @chuanzhen,

        Thank you for reaching out to us. There is no mechanism to get the state of a menu item as they are not meant to be the data layer of your app. You must store and track these values yourself; properties are a good pattern to solve such things, as you can encapsulate the GUI-DATA bindings in a very clean way with them. See end of my posting for a small example.

        Cheers,
        Ferdinand

        An example output:

        
        MY_DIALOG.IsFiles = False
        MY_DIALOG.IsFolders = False
        
        self._isFiles = True
        self._isFolders = True
        self._isFiles = False
        self._isFolders = False
        self._isFiles = True
        

        The code:

        """Provides a simple example for handling checkable menu items and their state with properties 
        inside a GeDialog instance. 
        """
        
        import c4d
        
        class MyDialog (c4d.gui.GeDialog):
            """Implements a dialog which encapsulates menu item states in properties.
            """
            ID_MENU_DATA_FILES: int = 1000 # The ID for the "Files" menu item.
            ID_MENU_DATA_FOLDERS: int = 1001 # The ID for the "Folders" menu item.
        
            def __init__(self) -> None:
                """Initializes the dialog.
                """
                self._isFiles: bool = False # The internal field for the IsFiles property.
                self._isFolders: bool = False # The internal field for the IsFolders property.
        
                super().__init__()
        
            def CreateLayout(self) -> bool:
                """Called by Cinema 4D to populate the dialog with gadgets.
                """
                # We build a very simply menu with the structure:
                #   Data
                #   +-- Files
                #   +-- Folders
                self.MenuSubBegin("Data")
                self.MenuAddString(MyDialog.ID_MENU_DATA_FILES, "Files")
                self.MenuAddString(MyDialog.ID_MENU_DATA_FOLDERS, "Folders")
                self.MenuSubEnd()
                self.MenuFinished()
        
                return super().CreateLayout()
        
            def Command(self, cid: int, data: c4d.BaseContainer) -> bool:
                """Called by Cinema 4D when a gadget, including menus, has been invoked.
                """
                # When one of the menu items has been invoked, we simply toggle the matching property.
                if cid == MyDialog.ID_MENU_DATA_FILES:
                    self.IsFiles = not self.IsFiles
        
                if cid == MyDialog.ID_MENU_DATA_FOLDERS:
                    self.IsFolders = not self.IsFolders
                    
                return super().Command(cid, data)
        
            # --- The menu items realized as properties ----------------------------------------------------
        
            @property
            def IsFiles(self) -> bool:
                """Gets the "Files" state.
        
                We just get the value from the private field.
                """
                return self._isFiles
        
            @IsFiles.setter
            def IsFiles(self, value: bool) -> None:
                """Sets the "Files" state.
        
                The setter also updates the GUI via GeDialog.MenuInitString, making sure that the properties
                are always correctly reflected. In this case we also print out the new value to demonstrate
                how the dialog works.
                """
                if not isinstance(value, bool):
                    raise TypeError(value)
                if self._isFiles == value:
                    return
        
                self._isFiles = value
                self.MenuInitString(MyDialog.ID_MENU_DATA_FILES, enabled=True, value=self._isFiles)
                print (f"{self._isFiles = }")
        
            @property
            def IsFolders(self) -> bool:
                """Gets the "Folders" state.
                """
                return self._isFolders
        
            @IsFolders.setter
            def IsFolders(self, value: bool) -> None:
                """Sets the "Folders" state.
                """
                if not isinstance(value, bool):
                    raise TypeError(value)
                if self._isFolders == value:
                    return
        
                self._isFolders = value
                self.MenuInitString(MyDialog.ID_MENU_DATA_FOLDERS, enabled=True, value=self._isFolders)
                print (f"{self._isFolders = }")
        
        # Attribute deceleration for a MyDialog instance used by main().
        MY_DIALOG: MyDialog
        
        def main():
            """Runs the example.
            """
            # We are using here the global attribute hack to make the dialog work in async mode in a Script
            # Manager script. Please do not use this hack in a production environment, Script Manger scripts
            # should not open async dialogs, they are restricted to plugins as they can properly manage the
            # lifetime of the dialog.
        
            global MY_DIALOG
            MY_DIALOG = MyDialog()
            
            # Open the dialog in asynchronous mode.
            MY_DIALOG.Open(c4d.DLG_TYPE_ASYNC, defaultw=200, defaulth=100)
        
            # We can now either directly read and write the properties of the dialog ...
            print (f"\n{MY_DIALOG.IsFiles = }")
            print (f"{MY_DIALOG.IsFolders = }\n")
            MY_DIALOG.IsFiles = True
        
            # or interact via GeDialog.Command with the dialog to toggle the properties and their GUI.
            MY_DIALOG.Command(MY_DIALOG.ID_MENU_DATA_FOLDERS, c4d.BaseContainer())
        
        if __name__ == "__main__":
            main()
        

        MAXON SDK Specialist
        developers.maxon.net

        chuanzhenC 1 Reply Last reply Reply Quote 1
        • chuanzhenC
          chuanzhen @ferdinand
          last edited by

          @ferdinand Thanks!

          相信我,可以的!

          1 Reply Last reply Reply Quote 0
          • First post
            Last post