Dialog Plugin with Progress Bar or SetStatusBar
-
hi,
welcome to our forum
please have a look at our forum guidelines to use the tag functionality and "ask question" .I would say that this depend on how fast is your action, if you are renaming only a few objects that can be so fast that you don't really have time to see the progess bar.
The example below show the difference, the "short" task will barely show the progress bar.import c4d from c4d import gui class TestDialog(gui.GeDialog): PROGRESSBAR = 1001 ID_BTN_01 = 1002 ID_BTN_02 = 1003 def __init__(self): self.progress = 0 def StopProgress(self): self.progress = 0 progressMsg = c4d.BaseContainer(c4d.BFM_SETSTATUSBAR) progressMsg.SetBool(c4d.BFM_STATUSBAR_PROGRESSON, False) self.SendMessage(self.PROGRESSBAR, progressMsg) def CreateLayout(self): self.SetTitle("ProgressBar Example") self.GroupBegin(id=1000, flags=c4d.BFH_SCALEFIT|c4d.BFV_TOP, cols=0, rows=1) self.AddCustomGui(self.PROGRESSBAR, c4d.CUSTOMGUI_PROGRESSBAR, "", c4d.BFH_SCALEFIT|c4d.BFV_SCALEFIT, 0, 0) self.GroupEnd() self.GroupBegin(id = 1005, flags=c4d.BFH_SCALEFIT|c4d.BFV_TOP, cols=2, rows=1) self.AddButton(self.ID_BTN_01, c4d.BFH_SCALEFIT, 100, 15, name="Do Something short") self.AddButton(self.ID_BTN_02, c4d.BFH_SCALEFIT, 100, 15, name="Do Something longer") self.GroupEnd() return True def Command(self, id, msg): if (id == self.ID_BTN_01): #do something short opecnt = 100; for x in range(opecnt): self.progress += 1 progressMsg = c4d.BaseContainer(c4d.BFM_SETSTATUSBAR) progressMsg[c4d.BFM_STATUSBAR_PROGRESSON] = True progressMsg[c4d.BFM_STATUSBAR_PROGRESS] = self.progress/opecnt self.SendMessage(self.PROGRESSBAR, progressMsg) self.StopProgress() if (id == self.ID_BTN_02): # do seomthing longer opecnt = 10000; for x in range (opecnt): self.progress += 1 progressMsg = c4d.BaseContainer(c4d.BFM_SETSTATUSBAR) progressMsg[c4d.BFM_STATUSBAR_PROGRESSON] = True progressMsg[c4d.BFM_STATUSBAR_PROGRESS] = self.progress/opecnt self.SendMessage(self.PROGRESSBAR, progressMsg) self.StopProgress() return True def AskClose(self): self.StopProgress() return False if __name__=='__main__': dialog = TestDialog() dialog.Open(dlgtype=c4d.DLG_TYPE_ASYNC, pluginid=0, defaulth=400, defaultw=400)
Cheers,
Manuel -
Hi Manuel,
thanks for your the time and the example code.
I’m aware that depending on the time the execution of my action takes, the process of updating the progress bar can take more or less time. Just to be sure I didn’t overlook some fundamental things, I gave your code a shot and well what can I say – it doesn’t work.
I try to explain more clearly whats happening. If I run it as is I don’t even get a bar to see. I have to comment the
self.StopProgress()
method to actually see a bar at all. (This is maybe what you were referring to by saying: „… don’t really have time to see the progess bar…“I then increased the count in your example to 100.000 and all I’m getting is a sort of freezing Cinema and a beachball of death (macOS mouse cursor) while it is running. When it’s done the progress bar is updated up to 100% in one go. When really what I want is an real time updating progress bar that has a 1:1 relationship with my selected objects/materials, etc…
Is this maybe a macOS related problem (as the examples in my first post didn’t work as well and the guy in the video was clearly running Windows)? Or do I have to this kind of progress bar updating from another thread? And if so – how would I go about it?
BTW I dont’t want to mix up things here, but the same goes for
c4d.StatusSetBar()
. Setting the percentage in a loop doesn’t incrementally update the bar.Cheers,
Sebastian -
hi,
my bad, on mac, it's a lot faster than on windows.
If i add a sleep on the code (making it a lot slower) than the progress bar is there.
if you don't add time and make 100000 loop, you will see the bar update twice (or something like that).
You can't ask the UI to be refresh 100000 in one second.I would try to see how many time my code take to do its job.
import c4d from c4d import gui import time class TestDialog(gui.GeDialog): PROGRESSBAR = 1001 ID_BTN_01 = 1002 ID_BTN_02 = 1003 def __init__(self): self.progress = 0 def StopProgress(self): print("stop progress") self.progress = 0 progressMsg = c4d.BaseContainer(c4d.BFM_SETSTATUSBAR) progressMsg.SetBool(c4d.BFM_STATUSBAR_PROGRESSON, False) self.SendMessage(self.PROGRESSBAR, progressMsg) def CreateLayout(self): self.SetTitle("ProgressBar Example") self.GroupBegin(id=1000, flags=c4d.BFH_SCALEFIT|c4d.BFV_TOP, cols=0, rows=1) self.AddCustomGui(self.PROGRESSBAR, c4d.CUSTOMGUI_PROGRESSBAR, "", c4d.BFH_SCALEFIT|c4d.BFV_SCALEFIT, 0, 0) self.GroupEnd() self.GroupBegin(id = 1005, flags=c4d.BFH_SCALEFIT|c4d.BFV_TOP, cols=2, rows=1) self.AddButton(self.ID_BTN_01, c4d.BFH_SCALEFIT, 100, 15, name="Do Something short") self.AddButton(self.ID_BTN_02, c4d.BFH_SCALEFIT, 100, 15, name="Do Something longer") self.GroupEnd() return True def Command(self, id, msg): if (id == self.ID_BTN_01): #do something short opecnt = 100; for x in range(opecnt): self.progress += 1 progressMsg = c4d.BaseContainer(c4d.BFM_SETSTATUSBAR) progressMsg[c4d.BFM_STATUSBAR_PROGRESSON] = True progressMsg[c4d.BFM_STATUSBAR_PROGRESS] = self.progress/opecnt self.SendMessage(self.PROGRESSBAR, progressMsg) self.StopProgress() if (id == self.ID_BTN_02): # do seomthing longer opecnt = 10000; for x in range (opecnt): time.sleep(0.0001) self.progress += 1 progressMsg = c4d.BaseContainer(c4d.BFM_SETSTATUSBAR) progressMsg[c4d.BFM_STATUSBAR_PROGRESSON] = True progressMsg[c4d.BFM_STATUSBAR_PROGRESS] = self.progress/opecnt self.SendMessage(self.PROGRESSBAR, progressMsg) self.StopProgress() return True def AskClose(self): self.StopProgress() return False if __name__=='__main__': dialog = TestDialog() dialog.Open(dlgtype=c4d.DLG_TYPE_ASYNC, pluginid=0, defaulth=400, defaultw=400)
cheers
Manuel -
Hi Manuel,
hmm… that’s weird. Tried that code as well but the progress bar is still not showing up.
I recorded a small screen capture for you to see what i meant by saying: “…I don’t even get a bar to see…“
Maybe this will make things clearer.Cheers,
Sebastian -
Hi @HerrMay looks like you are in R18 meaning you are using Python 2.7 which by default do an int division so changing
self.progress += 1
toself.progress += 1.0
will force a float division and give the expected result (the short one will produce nothing since it's executed too fast but the long one work)Cheers,
Maxime. -
Hi @m_adam,
I’m sorry, but nope that doesn’t change anything. I mean you’re right Python 2.7 is doing integer division by default but forcing a float division doesn’t do it for me here. As you can see in my screencast the UI is kind of blocked when I hit the button for „do something longer“. The progress bar only shows up if I comment
self.StopProgress()
. BUT it is then showing up completely full and not constantly updating like in Manuels example.By now I slowly get the feeling that it is simply not working this way. To me it looks like the UI is blocking the update process. But then again I don’t understand why it is working in Manuels example. Since he is clearly executing the code on macOS as I do.
-
Here it's working as expected in R18 could you try the next code (use the Do something Longer button) (this is the same Manuel posted with the float modification)
import c4d from c4d import gui import time class TestDialog(gui.GeDialog): PROGRESSBAR = 1001 ID_BTN_01 = 1002 ID_BTN_02 = 1003 def __init__(self): self.progress = 0 def StopProgress(self): print("stop progress") self.progress = 0 progressMsg = c4d.BaseContainer(c4d.BFM_SETSTATUSBAR) progressMsg.SetBool(c4d.BFM_STATUSBAR_PROGRESSON, False) self.SendMessage(self.PROGRESSBAR, progressMsg) def CreateLayout(self): self.SetTitle("ProgressBar Example") self.GroupBegin(id=1000, flags=c4d.BFH_SCALEFIT|c4d.BFV_TOP, cols=0, rows=1) self.AddCustomGui(self.PROGRESSBAR, c4d.CUSTOMGUI_PROGRESSBAR, "", c4d.BFH_SCALEFIT|c4d.BFV_SCALEFIT, 0, 0) self.GroupEnd() self.GroupBegin(id = 1005, flags=c4d.BFH_SCALEFIT|c4d.BFV_TOP, cols=2, rows=1) self.AddButton(self.ID_BTN_01, c4d.BFH_SCALEFIT, 100, 15, name="Do Something short") self.AddButton(self.ID_BTN_02, c4d.BFH_SCALEFIT, 100, 15, name="Do Something longer") self.GroupEnd() return True def Command(self, id, msg): if (id == self.ID_BTN_01): #do something short opecnt = 100 for x in range(opecnt): self.progress += 1.0 progressMsg = c4d.BaseContainer(c4d.BFM_SETSTATUSBAR) progressMsg[c4d.BFM_STATUSBAR_PROGRESSON] = True progressMsg[c4d.BFM_STATUSBAR_PROGRESS] = self.progress / opecnt self.SendMessage(self.PROGRESSBAR, progressMsg) self.StopProgress() if (id == self.ID_BTN_02): # do seomthing longer opecnt = 10000; for x in range (opecnt): time.sleep(0.0001) self.progress += 1.0 progressMsg = c4d.BaseContainer(c4d.BFM_SETSTATUSBAR) progressMsg[c4d.BFM_STATUSBAR_PROGRESSON] = True progressMsg[c4d.BFM_STATUSBAR_PROGRESS] = self.progress / opecnt self.SendMessage(self.PROGRESSBAR, progressMsg) self.StopProgress() return True def AskClose(self): self.StopProgress() return False if __name__=='__main__': dialog = TestDialog() dialog.Open(dlgtype=c4d.DLG_TYPE_ASYNC, pluginid=0, defaulth=400, defaultw=400)
-
Hi @m_adam,
I tried your code as well but still no luck…
However in R20 it is working as expected. So maybe after all it is R18 related?Cheers,
Sebastian -
Hi @HerrMay sorry for the late reply, just re-checking and I can indeed confirm it doesn't work on R18 MAC. However, this is fixed in R19 mac and it's working correctly on windows.
Unfortunately, we don't support more than 2 versions, so R18 is out of scope, and since the issue comes from Cinema 4D side, I don't see a way for you to fix it.
Sorry for the long wait for just confirm that it doesn't work...
Cheers,
Maxime. -
Hi @m_adam,
ah, okay I see. I was afraid that this would be the case.
However, thank you for clarification. You can close this thread if you like.
Cheers,
Sebastian -
Hello @HerrMay,
thank you for your reply. Please note that we prefer users to flag topics as solved, as doing it ourselves always comes with the danger of erroneously flagging a posting as solved. Please refer to our Forum Guidelines - Forum Feature: Ask as Question in case you do not know how to do this.
Cheers,
Ferdinand -