Dialog generates EVMSG_CHANGE messages
-
Hi,
I am running into this problem that when create a dialog and keep its reference alive it generates an EVMSG_CHANGE message whenever I click in the viewport.
I am using Cinema 4D R21.115 on windows.
Here is a small test I created that does not generate any EVMSG_CHANGE messages.
import c4d class CollectionManager(c4d.gui.GeDialog): def CoreMessage(self, kind, data): if kind == c4d.EVMSG_CHANGE: print("Something changed") return super(CollectionManager, self).CoreMessage(kind, data) # Main function def main(): dialog = CollectionManager() dialog.Open(c4d.DLG_TYPE_ASYNC, 1040130) # Execute main() if __name__=='__main__': main()
Here is the same code with the only difference being that the variable dialog has been moved out of the function and into the global scope. This generates EVMSG_CHANGE messages whenever I click in the viewport/editor window.
import c4d class CollectionManager(c4d.gui.GeDialog): def CoreMessage(self, kind, data): if kind == c4d.EVMSG_CHANGE: print("Something changed") return super(CollectionManager, self).CoreMessage(kind, data) # Main function dialog = CollectionManager() def main(): dialog.Open(c4d.DLG_TYPE_ASYNC, 1040130) # Execute main() if __name__=='__main__': main()
It might be something that don't quite understand but any help would be greatly appreciated.
Best Regards,
Alamgir Nasir -
The Script Manager doesn't have official support for DLG_TYPE_ASYNC but only for Modal (blocking) dialog since that means your variable (your dialog) must live for a longer time than the executed script.
Which we can't grant.So the second script works because you moved the dialog definition outside of the main function, so the dialog variable is now a global variable.
But in any case, it's not really a good thing, while it's working, at each execution of the Script Manager, the scope is renewed meaning all global variables are trashed. Since the internal Python Object who is responsible for the GeDialog host does not longer exist, nothing delete this GeDialog instance in memory it means you will create a lot of memory leak (ram usage will increase without a way to free it except restart Cinema 4D).
Cheers,
Maxime. -
@m_adam said in Dialog generates EVMSG_CHANGE messages:
So the second script works because you moved the dialog definition outside of the main function, so the dialog variable is now a global variable. But in any case, it's not really a good thing, since at each execution, the scope is renewed (meaning all global variable trashed, so you will create a memory leak).
The second script is the one that does NOT work, meaning that it produces EVMSG_CHANGE messages. I took this code out of a much larger piece of code that is run from the plugins folder when cinema starts not the script manager it also does not use global variables, this was only meant for the demonstration of the problem with the minimum amount of code. In the actual use case the dialog is being created by a command data plugin and saved as a member variable. The problem still persists.
The command data plugin that creates the dialog:
class CollectionManagerCommand(c4d.plugins.CommandData): dialog = CollectionManager() def Execute(self, doc): return self.dialog.Open(c4d.DLG_TYPE_ASYNC, res.COLLECTION_MANAGER_PLUGIN_ID) def RestoreLayout(self, secret): return self.dialog.Restore(res.COLLECTION_MANAGER_PLUGIN_ID, secret) def register(self): return c4d.plugins.RegisterCommandPlugin(res.COLLECTION_MANAGER_PLUGIN_ID, res.string('IDS_COLLECTIONMANAGER'), c4d.PLUGINFLAG_HIDEPLUGINMENU, res.bitmap('res/icons/manager.png'), "", self)
-
I found the problem this is not the issue.