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

    Command() does not honor Dynamic Lists/Variable

    Cinema 4D SDK
    r21 python
    3
    9
    899
    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.
    • B
      bentraje
      last edited by

      Hi,

      For some reason, the dynamic list exists on the CreateLayout() but entirely nonexistent on the Command().

      The resulting code below output this
      Button ID List under CreateLayout()[101012, 101013, 101014, 101015, 101016, 101017, 101018, 101019, 101020]
      Button ID List under Command() []

      I would expect the both output the same list since they are in the same variable, but they don't.
      Is there a way around this?

      You can check the working code here:

      import c4d
      from c4d import bitmaps, documents, gui, plugins, threading, utils
      
      PLUGIN_ID   = 987654321
      
      class MyDialog(gui.GeDialog):
      
          def __init__(self):
              self.button_id_list = []
      
      
          def InitValues(self):
              self.button_id_list = []
              
              return True
      
          def CreateLayout(self):
      
              self.SetTitle('Button Problem')
              
              self.GroupBegin(id=202020, flags=c4d.BFH_FIT, cols=1, title="General")
      
              total_buttons = 10
      
              for x in range(1, total_buttons):            
                  button_id = x + 101011
                  self.button_id_list.append(button_id)
                  self.AddButton(button_id, c4d.BFH_CENTER, initw=100, inith=10, name="Button ID " + str(button_id))
       
              self.GroupEnd()
      
              print "Button ID List under CreateLayout()", self.button_id_list
      
              return True
      
          def Command(self, id, msg):
      
      
              print "Button ID List under Command()", self.button_id_list
             
              return True
      
      class MyMenuPlugin(plugins.CommandData):
      
          dialog = None
          def Execute(self, doc):
          # create the dialog
             if self.dialog is None:
                self.dialog = MyDialog()
      
             return self.dialog.Open(dlgtype=c4d.DLG_TYPE_ASYNC, pluginid=PLUGIN_ID, defaultw=200, defaulth=150, xpos=-1, ypos=-1)
      
          def RestoreLayout(self, sec_ref):
          # manage the dialog
             if self.dialog is None:
                self.dialog = MyDialog()
             return self.dialog.Restore(pluginid=PLUGIN_ID, secret=sec_ref)
      
      if __name__ == "__main__":
      
          okyn = plugins.RegisterCommandPlugin(PLUGIN_ID, "ButtonID",0, None, "ButtonID", MyMenuPlugin())
          if (okyn):
              print "ButtonID"
      
      ``
      1 Reply Last reply Reply Quote 0
      • M
        mp5gosu
        last edited by mp5gosu

        On InitValues(), you're resetting the list. Since InitValues() is usually called once one construction(if done right) and CreateLayout() everytime, the Dialog is opened your list is reset.

        M 1 Reply Last reply Reply Quote 0
        • M
          m_adam @mp5gosu
          last edited by m_adam

          Just to add some extra information about what's @mp5gosu,

          InitValues is called only the first time the dialog is opened, not all time after CreateLayout.
          So this way if you have some value in your GeDialog, you close it, reopen it (if it's the same instance) values within the Dialog are still similar and not reset.

          Cheers,
          Maxime.

          MAXON SDK Specialist

          Development Blog, MAXON Registered Developer

          1 Reply Last reply Reply Quote 0
          • M
            mp5gosu
            last edited by

            edited my answer accordingly. Messed up the order. 😉

            1 Reply Last reply Reply Quote 0
            • B
              bentraje
              last edited by

              @mp5gosu and @m_adam

              Thanks for the rest, but I'm not sure what exactly is the solution.

              I tried with this one but it still gives me zero list. I kinda need the live self.button_id_list to also live under the Command.

                  def Command(self, id, msg):
              
                      self.InitValues()
                      print "Button ID List under Command()", self.button_id_list
                     
                      return True
              
              1 Reply Last reply Reply Quote 0
              • M
                m_adam
                last edited by m_adam

                You should have a reset somewhere else in your code using the code you provided with the change on InitValues work as expected.

                import c4d
                
                class TestDialog(c4d.gui.GeDialog):
                    def __init__(self):
                        self.button_id_list = []
                
                
                    def InitValues(self):        
                        return True
                
                    def CreateLayout(self):
                
                        self.SetTitle('Button Problem')
                        
                        self.GroupBegin(id=202020, flags=c4d.BFH_FIT, cols=1, title="General")
                
                        total_buttons = 10
                
                        for x in range(1, total_buttons):            
                            button_id = x + 101011
                            self.button_id_list.append(button_id)
                            print button_id
                            self.AddButton(button_id, c4d.BFH_SCALEFIT, initw=0, inith=10, name="Button ID " + str(button_id))
                 
                        self.GroupEnd()
                
                        print "Button ID List under CreateLayout()", self.button_id_list
                
                        return True
                
                    def Command(self, id, msg):
                        print id
                
                        print "Button ID List under Command()", self.button_id_list
                       
                        return True
                
                if __name__ == '__main__':
                    global dlg
                    dlg = TestDialog()
                    dlg.Open(dlgtype=c4d.DLG_TYPE_ASYNC)
                

                Cheers,
                Maxime.

                MAXON SDK Specialist

                Development Blog, MAXON Registered Developer

                1 Reply Last reply Reply Quote 0
                • B
                  bentraje
                  last edited by

                  @m_adam

                  Thanks for the code. It seems to work as expected.
                  You mentioned reset and I assumed it is just a matter of moving the InitValues() command but it turns out InitValues is not being used.

                  So basically, don't put any variable in InitValues if it is to be used in Command()?

                  Is this assessment correct?

                  1 Reply Last reply Reply Quote 0
                  • M
                    m_adam
                    last edited by m_adam

                    Let's re-take everything together.

                    1. Cinema 4D Call __init__() because you initialize the GeDialog class.
                      • 1.1: Here you create an empty list called button_id_list stored in the class instance.
                    2. You call dialog.Open()
                      • 2.1: Cinema 4D call CreateLayout.
                        • 2.1.1: You add some data to button_id_list.
                      • 2.2: Cinema 4D call InitValues if it's the first time this instance of the dialog is opened.
                        • 2.2.1: You reset the value of button_id_list to an empty list.
                    3. A user presses a button.
                      • Cinema 4D call Command with the gadget ID the user clicked.
                        • Due to step 2.2.1, you button_id_list is empty so no way to retrieve the data.

                    And what I'm saying by You should have a reset somewhere else in your code is if the initial code you provided on this topic, didn't work even after removing the self.button_id_list = [] of your InitValues, then that means you have another self.button_id_list = [] in your code somewhere else.

                    Cheers,
                    Maxime.

                    MAXON SDK Specialist

                    Development Blog, MAXON Registered Developer

                    1 Reply Last reply Reply Quote 1
                    • B
                      bentraje
                      last edited by

                      When you presented the order of execution of __init__(), CreateLayout and InitValues. That makes total sense especially the 2.2.1 when it resets to an empty list.

                      Thanks for the clarification!

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