Command() does not honor Dynamic Lists/Variable
-
Hi,
For some reason, the dynamic list exists on the
CreateLayout()
but entirely nonexistent on theCommand()
.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. SinceInitValues()
is usually called once one construction(if done right) andCreateLayout()
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.
-
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 theCommand
.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. -
Thanks for the code. It seems to work as expected.
You mentioned reset and I assumed it is just a matter of moving theInitValues()
command but it turns outInitValues
is not being used.So basically, don't put any variable in
InitValues
if it is to be used inCommand()
?Is this assessment correct?
-
Let's re-take everything together.
- 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.
- 1.1: Here you create an empty list called
- You call dialog.Open()
- 2.1: Cinema 4D call CreateLayout.
- 2.1.1: You add some data to
button_id_list
.
- 2.1.1: You add some data to
- 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.
- 2.2.1: You reset the value of
- 2.1: Cinema 4D call CreateLayout.
- 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.
- Due to step 2.2.1, you
- Cinema 4D call Command with the gadget ID the user clicked.
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. - Cinema 4D Call
-
When you presented the order of execution of
__init__()
,CreateLayout
andInitValues
. That makes total sense especially the 2.2.1 when it resets to an empty list.Thanks for the clarification!