Maxon Developers Maxon Developers
    • Documentation
      • Cinema 4D Python API
      • Cinema 4D C++ API
      • Cineware API
      • ZBrush Python API
      • ZBrush GoZ API
      • Code Examples on Github
    • Forum
    • Downloads
    • Support
      • Support Procedures
      • Registered Developer Program
      • Plugin IDs
      • Contact Us
    • Categories
      • Overview
      • News & Information
      • Cinema 4D SDK Support
      • Cineware SDK Support
      • ZBrush 4D SDK Support
      • Bugs
      • General Talk
    • Recent
    • Tags
    • Users
    • Login

    Update Status bar from inside a script

    Scheduled Pinned Locked Moved PYTHON Development
    13 Posts 0 Posters 1.2k Views
    Loading More Posts
    • Oldest to Newest
    • Newest to Oldest
    • Most Votes
    Reply
    • Reply as topic
    Log in to reply
    This topic has been deleted. Only users with topic management privileges can see it.
    • H Offline
      Helper
      last edited by

      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()
      
      1 Reply Last reply Reply Quote 0
      • H Offline
        Helper
        last edited by

        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()   
        
        1 Reply Last reply Reply Quote 0
        • H Offline
          Helper
          last edited by

          On 24/07/2016 at 07:26, xxxxxxxx wrote:

          I have already tried:

            
          c4d.EventAdd(c4d.EVENT_FORCEREDRAW)   
          

          and

            
          c4d.SendCoreMessage(c4d.COREMSG_CINEMA,c4d.BaseContainer(c4d.COREMSG_CINEMA_FORCE_AM_UPDATE))   
          

          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.

          1 Reply Last reply Reply Quote 0
          • H Offline
            Helper
            last edited by

            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.

            FYI:
            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.

            -ScottA

            1 Reply Last reply Reply Quote 0
            • H Offline
              Helper
              last edited by

              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.
              Very weird.

              1 Reply Last reply Reply Quote 0
              • H Offline
                Helper
                last edited by

                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.

                -ScottA

                1 Reply Last reply Reply Quote 0
                • H Offline
                  Helper
                  last edited by

                  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:

                  1 Reply Last reply Reply Quote 0
                  • H Offline
                    Helper
                    last edited by

                    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.

                    -ScottA

                    1 Reply Last reply Reply Quote 0
                    • H Offline
                      Helper
                      last edited by

                      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.

                      1 Reply Last reply Reply Quote 0
                      • H Offline
                        Helper
                        last edited by

                        On 25/07/2016 at 02:21, xxxxxxxx wrote:

                        Hello,

                        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.

                        Best wishes,
                        Sebastian

                        1 Reply Last reply Reply Quote 0
                        • H Offline
                          Helper
                          last edited by

                          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.

                          1 Reply Last reply Reply Quote 0
                          • H Offline
                            Helper
                            last edited by

                            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.

                            1 Reply Last reply Reply Quote 0
                            • First post
                              Last post