EventAdd doesn't work with a modal dialog in C4D 2026
-
Hi! I noticed that in Cinema 4D 2026.1.2, c4d.EventAdd() doesn't work when it's executed with a modal dialog. With an async dialog it works just fine. In Cinema 4D 2025.3.3 both dialog types works just fine. Has something changed? Do I need to call c4d.EventAdd() somewhere else to use it with a modal dialog?
Example code
import c4d from c4d import gui doc: c4d.documents.BaseDocument op: c4d.BaseObject | None class Dialog(gui.GeDialog): def __init__(self): super(Dialog, self).__init__() self.res = c4d.BaseContainer() def CreateLayout(self): self.SetTitle("Test") self.GroupBegin(1000, c4d.BFH_LEFT | c4d.BFH_SCALEFIT, 1, 2) self.GroupBorderSpace(5, 5, 5, 5) self.AddButton(1001, c4d.BFH_LEFT, name="OK") self.GroupEnd() return True def Command(self, paramid, msg): if paramid == 1001: null = c4d.BaseObject(c4d.Onull) doc.InsertObject(null) c4d.EventAdd() self.Close() return True dlg = Dialog() dlg.Open(c4d.DLG_TYPE_MODAL_RESIZEABLE, pluginid=0, xpos=-1, ypos=-1, defaultw=0)In the example the null object is inserted to the document and it should appear instantly after pressing the OK button.
-
Hey @aturtur,
Thank you for reaching out to us.
EventAddwill never really work in script manager scripts in the sense you mean it, unless you use hacks like dangling async dialogs (which as I always point out are a really bad idea).The reason is that Script Manager scripts are blocking, i.e., all scene and GUI execution is being halted until the script finishes. You can hack yourself around this with a dangling async dialog, i.e., a dialog that lives beyond the life time of its script. But that is not a good idea, you should implement some form of plugin to host your asnyc dialog, as you otherwise risk crashes.
A modal dialog is just an extension of this. It is right in the name, it is modal, i.e., synchronous. All scene and GUI execution is being halted while this dialog is open and only resumes once it closes. When you want updates while your dialog is open, you need an async dialog (and a plugin which hosts it).
Cheers,
FerdinandSince you also might misunderstand the nature of
EventAdd()I am also putting here the C++ docs I updated a few weeks ago, to better reflect the nature of it (not yet live):/// @brief Enqueues an update event for the active document. /// @details Only must be called when modifying the active document and is without meaning for other documents. The typical example of using `EventAdd` is after adding or removing elements from the active document; and wanting these changes to be reflected in the UI. The function itself is technically thread-safe, but the vast majority of operations that require calling `EventAdd` are not thread-safe and must be called from the main thread (and therefore calling this function is usually main thread bound). The function also does not enqueue a dedicated event item, but rather sets a flag that is checked when the next update event is processed. Therefore, calling `EventAdd` multiple times in one function scope is unnecessary overhead which must be avoided. Because such multiple event flags cannot be consumed while a function on the main thread is still running, and instead the event will only be consumed after that function returns. /// @code /// Result<void> AddCubes() /// { /// CheckState(maxon::ThreadInterface::IsMainThread(), "AddCubes must be called from the main thread."_s); /// /// // EventAdd(); // We could also technically call it here with the same effect. The event /// // will only happen after this function returns. /// /// BaseDocument* doc = GetActiveDocument(); /// for (int i = 0; i < 10; ++i) /// { /// BaseObject* cube = BaseObject::Alloc(Ocube); /// if (!cube) /// return maxon::OutOfMemoryError(MAXON_SOURCE_LOCATION, "Failed to allocate cube object."_s); /// /// doc->InsertObject(cube); /// /// // Calling EventAdd here would have no extra effect, since this event cannot be consumed while /// // our main thread function is still running. And such extra calls on a large scale can cause /// // considerable overhead. /// } /// /// // Notify C4D that the active document has changed. The very end of a function or scope is the /// // canonical place to call EventAdd(). /// EventAdd(); /// } /// @endcode /// @see The article @link page_manual_coremessages Core Messages@endlink for more information. /// @param[in] eventflag The event to add: @enumerateEnum{EVENT}