How to Communicate between SubDialog and main GeDialog
-
Hello,
I am trying to send messages from a SubDialog to a parent GeDialog. I am using a variation of this example implementation from NiklasR.import c4d PLUGIN_ID = 1000004 # Test ID ACTION_ID = 123456 class MainDialog(c4d.gui.GeDialog): @property def sub_dialog(self): if not hasattr(self, '_sub_dialog'): self._sub_dialog = SubDialog() return self._sub_dialog def CreateLayout(self): self.SetTitle('Main Dialog') self.AddButton(1000, 0, name="Open Sub-Dialog") return True def Message(self, msg, result): if msg.GetId() == ACTION_ID: print msg return c4d.gui.GeDialog.Message(self, msg, result) def Command(self, param, bc): print bc if param == 1000: self.sub_dialog.Open(c4d.DLG_TYPE_ASYNC, PLUGIN_ID, subid=1) return True def Restore(self, pluginid, secref): if secref['subid'] == 1: return self.sub_dialog.Restore(pluginid, secref) else: return super(MainDialog, self).Restore(pluginid, secref) class SubDialog(c4d.gui.GeDialog): def CreateLayout(self): self.SetTitle('Sub-Dialog') self.AddButton(1000, 0, name="Send Message") return True def Command(self, id, msg): if id == 1001: bc = c4d.BaseContainer() bc.SetId(c4d.BFM_ACTION) bc.SetInt32(c4d.BFM_ACTION_ID, ACTION_ID) self.SendParentMessage(bc) return True class Command(c4d.plugins.CommandData): def Register(self): return c4d.plugins.RegisterCommandPlugin( PLUGIN_ID, "Sub-Dialog Message", 0, None, "", self) @property def dialog(self): if not hasattr(self, '_dialog'): self._dialog = MainDialog() return self._dialog def Execute(self, doc): return self.dialog.Open(c4d.DLG_TYPE_ASYNC, PLUGIN_ID) def RestoreLayout(self, secref): return self.dialog.Restore(PLUGIN_ID, secref) if __name__ == '__main__': Command().Register()
I've tried using SendParentMessage but, for whatever reason, my parent dialog isn't receiving the message.
In my parent GeDialog I've tried using the Command and Message methods, but neither receives the message from the SubDialog.
Can anyone help? Thank you!
-
Hi @blastframe the main issue I guess is because of your SubDialog inherit from GeDial and not SubDialog.
Here a quick exampleimport c4d GADGET_ID_SUBDIALOG = 10000 MSG_ID_SUBDIALOG_LAYOUT_CREATED = 1000001 class SubDialogExample(c4d.gui.SubDialog): def CreateLayout(self): """ This Method is called automatically when Cinema 4D Create the Layout (display) of the SubDialog. """ # Creates a Static Text self.AddStaticText(1000, c4d.BFH_SCALEFIT | c4d.BFV_SCALEFIT, 0, 0, "First Sub Dialog", c4d.BORDER_THIN_IN) msgContainer = c4d.BaseContainer(MSG_ID_SUBDIALOG_LAYOUT_CREATED) self.SendParentMessage(msgContainer) return True class ExampleDialog(c4d.gui.GeDialog): # The SubDialog need to be stored somewhere, we will need this instance to be attached to the current Layout subDialog = SubDialogExample() def CreateLayout(self): """ This Method is called automatically when Cinema 4D Create the Layout (display) of the Dialog. """ # Adds a Gadget that will host a SubDialog self.AddSubDialog(GADGET_ID_SUBDIALOG, c4d.BFH_SCALEFIT | c4d.BFV_SCALEFIT, 100, 100) # Attaches the stored SubDialog to the Gadget previously created self.AttachSubDialog(self.subDialog, GADGET_ID_SUBDIALOG) return True def Message(self, msg, result): """ This Method is called automatically when the GeDialog receives a Message. :param msg: The message container. :param result: A container to place results in. """ # Messages is sent from the GeUserArea in line 65 if msg.GetId() == MSG_ID_SUBDIALOG_LAYOUT_CREATED: print("The GeUserArea, has been draw.") return True return super(ExampleDialog, self).Message(msg, result) def main(): # Creates a new instance of the GeDialog dlg = ExampleDialog() # Opens the GeDialog, since it's open it as Modal, it block Cinema 4D dlg.Open(c4d.DLG_TYPE_MODAL_RESIZEABLE, defaultw=300, defaulth=50) if __name__ == "__main__": main()
Cheers,
Maxime. -
@m_adam Hi Maxime, thank you for the reply.
I wasn't able to get it to work. I would like the Subdialog to be its own window, not attached to the Main Dialog. Is this possible? In the documentation for SendParentMessage it says the method is available for GeDialog but is it only for usage with GeUserArea? I don't think I understand the purpose of the Subdialog when used as a gadget. I see in the documentation for Subdialog that it inherits from GeDialog so shouldn't it be able to open as such? Thank you.
import c4d PLUGIN_ID = 1000004 # Test ID ACTION_ID = 123456 GADGET_ID_SUBDIALOG = 10000 class SubDialog(c4d.gui.SubDialog): def CreateLayout(self): self.SetTitle('Sub-Dialog') self.AddButton(1001, 0, name="Send Message") return True def Command(self, id, msg): if id == 1001: bc = c4d.BaseContainer() bc.SetId(c4d.BFM_ACTION) bc.SetInt32(c4d.BFM_ACTION_ID, ACTION_ID) self.SendParentMessage(bc) return True class MainDialog(c4d.gui.GeDialog): subDialog = SubDialog() def CreateLayout(self): self.SetTitle('Main Dialog') self.AddButton(1000, 0, name="Open Sub-Dialog") # Adds a Gadget that will host a SubDialog #self.AddSubDialog(GADGET_ID_SUBDIALOG, c4d.BFH_SCALEFIT | c4d.BFV_SCALEFIT, 100, 100) # Attaches the stored SubDialog to the Gadget previously created #self.AttachSubDialog(self.subDialog, GADGET_ID_SUBDIALOG) return True def Message(self, msg, result): if msg.GetId() == ACTION_ID: print "YES" return True return c4d.gui.GeDialog.Message(self, msg, result) def Command(self, param, bc): print bc if param == 1000: self.subDialog.Open(c4d.DLG_TYPE_ASYNC, PLUGIN_ID, subid=1) return True def Restore(self, pluginid, secref): if secref['subid'] == 1: return self.subDialog.Restore(pluginid, secref) else: return super(MainDialog, self).Restore(pluginid, secref) class Command(c4d.plugins.CommandData): def Register(self): return c4d.plugins.RegisterCommandPlugin( PLUGIN_ID, "Sub-Dialog Message", 0, None, "", self) @property def dialog(self): if not hasattr(self, '_dialog'): self._dialog = MainDialog() return self._dialog def Execute(self, doc): return self.dialog.Open(c4d.DLG_TYPE_ASYNC, PLUGIN_ID) def RestoreLayout(self, secref): return self.dialog.Restore(PLUGIN_ID, secref) if __name__ == '__main__': Command().Register()
-
Did you try my example which exactly demonstrate the use of a SubDialog?
SubDialog is about having a dialog embedded into another one.If you want to make communicate two independent GeDialog you have to use CoreMessage because there is no hierarchy between them they are both independent windows.
-
@m_adam Hi Maxime, I did try your example and I saw it working as a gadget but, you're right, I want to communicate between two GeDialogs. I followed your advice on using CoreMessage and found success with SpecialEventAdd. Thank you!