Update Status bar from inside a script
On 23/07/2016 at 08:29, xxxxxxxx wrote:
How can I update the status bar with c4d.StatusSetBar() and make it show the progress from inside a script?
Even if I place c4d.EventAdd() commands inside my loop, the status bar doesn't update.
On 23/07/2016 at 10:32, xxxxxxxx wrote:
You need to make your computer stop processing the script per iteration for a short period of time to see the value change take place using sleep().
import c4d, time def main() : for i in xrange(0, 101) : #Convert the value to a string. And add the percent symbol to it value = str(i) value += "%" c4d.StatusSetText( value ) time.sleep(.10) if __name__=='__main__': main()
On 23/07/2016 at 15:43, xxxxxxxx wrote:
It is still not working
Could it be that it is because I also have a dialog?
However, the main loop is after the Command method of the dialog closes the dialog (and, yet, the closing only really happens after the main loop finishes, don't really understand why).
This is, in a nutshell, my main loop:
lim=len(all_files) count=100.0/lim for c,i in enumerate(all_files) : # perform some stuff with the filename, inside the all_files list # copy and erase some files, based on the processed filename # only update the status every 100 items if c % 100 == 0: c4d.StatusSetBar(int(c*count)) c4d.StatusSetText("%s / %s" % (c,lim)) time.sleep(.1) c4d.StatusClear()
On 24/07/2016 at 07:26, xxxxxxxx wrote:
I have already tried:
All of it with a time.sleep(.25) in front... and nothing!!
I still get no refresh in the status bar.
I really would like to get some feedback to the user in the status bar, as the process can take a few seconds to finish.
On 24/07/2016 at 09:47, xxxxxxxx wrote:
I don't know about anyone else. But I'm not totally clear on what you're doing.
It sounds like you're having threading issues. But it's not clear to me.
Is there any way you can post a simple working example?
Something that runs, has a GeDialog in it, and your progress bar code in it.
I've noticed that the support guys don't usually answer questions on the weekends anymore like they used to.
They seem to be sticking to regular business hours now. Which is understandable.
So if you ask a question on Friday. It can take up to 3 days to get a reply from them.
On 24/07/2016 at 10:41, xxxxxxxx wrote:
I totally understand that and I know that if I post a question on Friday, I may only get and answer on Monday. So, I appreciate very much your help during these weekend days.
I'm writing a script. It is not a full plugin. So, I just have a GeDialog to define the parameters but my code, the one that should update the progress bar, is outside of the code of the dialog.
So, in my main I have this:
dlg=my_dialog() dlg.Open(c4d.DLG_TYPE_MODAL, defaultw=300, defaulth=50) the_path=dlg.the_path the_name=dlg.the_name if not dlg.ok: return
I have some variables inside the dialog class (the_path, the_name and ok).
If ok is True, the user pressed the OK button.
If ok is False, the user pressed the Cancel button.
This is all set in the Command method.
So, the code that follows the last line of code above is the one, inside the main that should update the progress bar.
A strange thing that occurs is that my Command method includes this:
def Command(self,id, msg) : if id==B_CANCEL: self.ok=False self.Close() return True if id==B_OK: self.ok=True self.Close() return True
...and the dialog closes if I press the Cancel button.
But if I press the OK button, the dialog only closes after my whole main loop finishes. And that is already outside the dialog code.
On 24/07/2016 at 11:45, xxxxxxxx wrote:
I'm afraid I'm still not clear on the problem.
Here is an example that implements the progressbar in two different places.
One is in the GeDialog's Command() method. The other one is executed in the main() method.
They are both working as expected for me.
import c4d, time from c4d import gui class MyDialog(gui.GeDialog) : BUTTON_ID = 1001 def CreateLayout(self) : self.AddButton(self.BUTTON_ID, c4d.BFH_SCALE|c4d.BFV_SCALE, 100, 25, "Close Dialog") return True def InitValues(self) : return True def Command(self, id, msg) : if id == self.BUTTON_ID: #If you use this code #The progressbar will update. Then the dialog will close when it's finished """for i in xrange(0, 101) : #Convert the value to a string. And add the percent symbol to it value = str(i) value += "%" c4d.StatusSetText( value ) time.sleep(.10)""" c4d.StatusClear() #Closes the dialog after the above code runs self.Close() return True if __name__=='__main__': dlg = MyDialog() dlg.Open(dlgtype=c4d.DLG_TYPE_MODAL, defaultw=200, defaulth=200) #If you use code #The dialog will close first. Then the progressbar will update """for i in xrange(0, 101) : #Convert the value to a string. And add the percent symbol to it value = str(i) value += "%" c4d.StatusSetText( value ) time.sleep(.10) c4d.StatusClear()"""
The only thing I can think of is to maybe try not using True after each button code. Just call True once at the end of the Command() method. But I doubt that would make a difference.
Sorry. I'm not being much help.
On 24/07/2016 at 12:02, xxxxxxxx wrote:
Well, I tried it, and... it doesn't work
I created a simple movie showing you what is happening:
On 24/07/2016 at 12:27, xxxxxxxx wrote:
It's works fine for me on a PC. You're using a mac right?
In the past I've had several mac users tell me that my dialog.Close() code did not work for them.
I don't own one so I can't test it. But based on my experiences, macs definitely have problem with the dialog.Close() function.
On 24/07/2016 at 14:30, xxxxxxxx wrote:
Thank you, Scott.
So, it is a Mac issue
Well, my code works, except for that problem.
I will try to find a workaround for it.
Damn!!! It should work fine on both platforms.
On 25/07/2016 at 02:21, xxxxxxxx wrote:
the following script works for me on both win and mac (R17 SP2) :
class TestDialog(gui.GeDialog) : def CreateLayout(self) : self.SetTitle("test") self.AddButton(1000, c4d.BFH_SCALEFIT | c4d.BFV_SCALEFIT, 0, 0, "Action") self.AddButton(2000, c4d.BFH_SCALEFIT | c4d.BFV_SCALEFIT, 0, 0, "Close") return True def Command(self, id, msg) : if id == 1000: for i in xrange(100) : time.sleep(.1) print(i) c4d.StatusSetBar(float(i)) c4d.StatusSetBar(float(-1)) if id == 2000: self.Close() return c4d.gui.GeDialog.Command(self, id, msg) def main() : dialog = TestDialog() dialog.Open(c4d.DLG_TYPE_MODAL_RESIZEABLE, 132456, -1 ,-1 ,400 ,400) if __name__=='__main__': main()
I think there are some differences on both Mac and Windows in regards to GUI handling so I cannot guarantee that this works in any situation.
On 25/07/2016 at 02:54, xxxxxxxx wrote:
I will try it as soon as I get home.
I'm at work now and I only have access to Windows machines.
Thank you, Sebastian.
On 26/07/2016 at 00:05, xxxxxxxx wrote:
Hello again, Sebastian.
I tried it and no Status Bar appears :-(
And the Console output is only shown in the end of the cycle.
So, no updates during the cycle.