Maxon Developers Maxon Developers
    • Documentation
      • Cinema 4D Python API
      • Cinema 4D C++ API
      • Cineware 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
    • Unread
    • Recent
    • Tags
    • Users
    • Login

    Dialog Plugin with Progress Bar or SetStatusBar

    Cinema 4D SDK
    python
    4
    12
    1.8k
    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
      HerrMay
      last edited by Manuel

      Hi folks,

      I’m fiddling around with the c4d.CUSTOMGUI_PROGRESSBAR and c4d.SetStatusBar in Python for quite a while now but can’t get it to work correctly. I’m trying to e.g rename a bunch of objects from a Dialog Plugin and set the progress bar accordingly.

      When I use the code from the example of this thread the bar is update accordingly to the Timer BUT the moment I put in my code to act on the selected objects, the objects get renamed and the bar immediately gets updated to 100% AFTER the renaming action. So no incremental update… Why is that? Is there any way to simultaneously do the work on the objects and have to bar update properly?

      I also found this code example where in a video is shown how its supposed to work. However when I use this I get the same behavior as described above. BTW it does make NO difference if I execute this code from the Script Manager or as a Plugin.

      I hope I could explained the problem well enough to follow. If not just let me know.
      Ah, before I forget I’m doing all this weirdness on macOS with R18.

      Cheers,
      Sebastian

      1 Reply Last reply Reply Quote 0
      • ManuelM
        Manuel
        last edited by

        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

        MAXON SDK Specialist

        MAXON Registered Developer

        1 Reply Last reply Reply Quote 0
        • H
          HerrMay
          last edited by

          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

          1 Reply Last reply Reply Quote 0
          • ManuelM
            Manuel
            last edited by Manuel

            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.

            progress_bar.gif

            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

            MAXON SDK Specialist

            MAXON Registered Developer

            1 Reply Last reply Reply Quote 0
            • H
              HerrMay
              last edited by

              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

              Example.gif

              1 Reply Last reply Reply Quote 0
              • M
                m_adam
                last edited by

                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 to self.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.

                MAXON SDK Specialist

                Development Blog, MAXON Registered Developer

                1 Reply Last reply Reply Quote 0
                • H
                  HerrMay
                  last edited by

                  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.

                  1 Reply Last reply Reply Quote 0
                  • M
                    m_adam
                    last edited by m_adam

                    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)
                    

                    MAXON SDK Specialist

                    Development Blog, MAXON Registered Developer

                    1 Reply Last reply Reply Quote 0
                    • H
                      HerrMay
                      last edited by

                      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

                      1 Reply Last reply Reply Quote 0
                      • M
                        m_adam
                        last edited by

                        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.

                        MAXON SDK Specialist

                        Development Blog, MAXON Registered Developer

                        1 Reply Last reply Reply Quote 0
                        • H
                          HerrMay
                          last edited by

                          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

                          1 Reply Last reply Reply Quote 0
                          • ferdinandF
                            ferdinand
                            last edited by

                            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

                            MAXON SDK Specialist
                            developers.maxon.net

                            1 Reply Last reply Reply Quote 0
                            • B bentraje referenced this topic on
                            • First post
                              Last post