Command() does not honor Dynamic Lists/Variable



  • 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"
    
    ``


  • 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.



  • 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.



  • edited my answer accordingly. Messed up the order. ;)



  • @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
    


  • 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.



  • @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?



  • 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.



  • 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!


Log in to reply