Skip to content
  • Categories
  • Recent
  • Tags
  • Popular
  • Users
  • Groups
  • Search
  • Get Qt Extensions
  • Unsolved
Collapse
Brand Logo
  1. Home
  2. Qt Development
  3. General and Desktop
  4. forcing update of dialog
Forum Updated to NodeBB v4.3 + New Features

forcing update of dialog

Scheduled Pinned Locked Moved Unsolved General and Desktop
20 Posts 6 Posters 2.0k Views 3 Watching
  • 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.
  • E Offline
    E Offline
    explorer100
    wrote on last edited by
    #5

    Thank you.. will try the update/repaint options.

    1 Reply Last reply
    0
    • E Offline
      E Offline
      explorer100
      wrote on last edited by
      #6

      Thank you all for the hints and advice.

      1 Reply Last reply
      0
      • E Offline
        E Offline
        explorer100
        wrote on last edited by explorer100
        #7

        The repaint worked beautifully as it updated the dialog from an external process where the update immediately displayed on the dialog while the rest of the program proceeded to do some calculation heavy activities (update() didn't work).

        I looked around to see what issues to look out for when using repaint() but did not find any info. I would appreciate any info on this.

        On a related note: I have a dialog that passes its progress bars to a library outside the dialog which in-tern updates the value of each of the progress bars (from the external library). It all works well as the progress bars change showing the progress in real time of the library functions (percent completions).

        But when some window is moved on top of this dialg then moved back, the dialog no longer shows any changes untill the library completes all its processing.

        Is there a way to circumvent this issue? I suppose the library can repaint() the progress bars?

        Pl45m4P S 2 Replies Last reply
        0
        • E explorer100

          The repaint worked beautifully as it updated the dialog from an external process where the update immediately displayed on the dialog while the rest of the program proceeded to do some calculation heavy activities (update() didn't work).

          I looked around to see what issues to look out for when using repaint() but did not find any info. I would appreciate any info on this.

          On a related note: I have a dialog that passes its progress bars to a library outside the dialog which in-tern updates the value of each of the progress bars (from the external library). It all works well as the progress bars change showing the progress in real time of the library functions (percent completions).

          But when some window is moved on top of this dialg then moved back, the dialog no longer shows any changes untill the library completes all its processing.

          Is there a way to circumvent this issue? I suppose the library can repaint() the progress bars?

          Pl45m4P Offline
          Pl45m4P Offline
          Pl45m4
          wrote on last edited by Pl45m4
          #8

          @explorer100 said in forcing update of dialog:

          I looked around to see what issues to look out for when using repaint() but did not find any info. I would appreciate any info on this.

          Info on what exactly?
          In most cases repaint() does what it says... it schedules the repainting of an area or widget (by invoking the paintEvent)

          while the rest of the program proceeded to do some calculation heavy activities (update() didn't work).

          In this

          But when some window is moved on top of this dialg then moved back, the dialog no longer shows any changes untill the library completes all its processing.

          and that regard it's hard to tell from your description what the issue is and what you are doing.
          Probably an issue with your app design.

          Note: Not visible (i.e. hidden) widgets are not updated.

          I suppose the library can repaint() the progress bars?

          Also not very clean... the library should not directly access your app's UI.

          On a related note: I have a dialog that passes its progress bars to a library outside the dialog

          That's also bad... Calculate the progress in your library (or wherever you need to) and send the update command to your GUI module, which holds your dialog and progress bar, so it will be updated from there.
          Accessing the GUI elements from all over the place or passing the elements around is not a good idea.


          If debugging is the process of removing software bugs, then programming must be the process of putting them in.

          ~E. W. Dijkstra

          E 1 Reply Last reply
          0
          • Pl45m4P Pl45m4

            @explorer100 said in forcing update of dialog:

            I looked around to see what issues to look out for when using repaint() but did not find any info. I would appreciate any info on this.

            Info on what exactly?
            In most cases repaint() does what it says... it schedules the repainting of an area or widget (by invoking the paintEvent)

            while the rest of the program proceeded to do some calculation heavy activities (update() didn't work).

            In this

            But when some window is moved on top of this dialg then moved back, the dialog no longer shows any changes untill the library completes all its processing.

            and that regard it's hard to tell from your description what the issue is and what you are doing.
            Probably an issue with your app design.

            Note: Not visible (i.e. hidden) widgets are not updated.

            I suppose the library can repaint() the progress bars?

            Also not very clean... the library should not directly access your app's UI.

            On a related note: I have a dialog that passes its progress bars to a library outside the dialog

            That's also bad... Calculate the progress in your library (or wherever you need to) and send the update command to your GUI module, which holds your dialog and progress bar, so it will be updated from there.
            Accessing the GUI elements from all over the place or passing the elements around is not a good idea.

            E Offline
            E Offline
            explorer100
            wrote on last edited by explorer100
            #9

            @Pl45m4 Note:

            You mentioned "Not visible (i.e. hidden) widgets are not updated."

            The situation I have is the widget is first updating properly, but when another window is on top of it, then removed from being on top of it, the updates stop.

            To your point of having the library call the ui's update function and the ui handles its internal data.. i agree. In this case, the dialog is calling the library to perform the library's function.

            I suppose the dialog could pass its' "self" to the library and the library would call its update function. which in tern would update the progress bars?

            I think this approach of passing the dialog would solve the update bars problem I described before.

            Pl45m4P 1 Reply Last reply
            0
            • E explorer100

              @Pl45m4 Note:

              You mentioned "Not visible (i.e. hidden) widgets are not updated."

              The situation I have is the widget is first updating properly, but when another window is on top of it, then removed from being on top of it, the updates stop.

              To your point of having the library call the ui's update function and the ui handles its internal data.. i agree. In this case, the dialog is calling the library to perform the library's function.

              I suppose the dialog could pass its' "self" to the library and the library would call its update function. which in tern would update the progress bars?

              I think this approach of passing the dialog would solve the update bars problem I described before.

              Pl45m4P Offline
              Pl45m4P Offline
              Pl45m4
              wrote on last edited by Pl45m4
              #10

              @explorer100 said in forcing update of dialog:

              I suppose the dialog could pass its' "self" to the library and the library would call its update function. which in tern would update the progress bars?

              No, as I've said before, why do you want to pass your GUI elements around for them to receive their updates elsewhere?!
              Whether you pass the whole dialog or just the progressbar makes no difference designwise.
              Depends on what type of library you have and its purpose. If it's solely for doing some tasks in the background, it should not access the GUI directly.
              If your dialog should display the progress of some calculations made in your library, then send the update (the values) to your main GUI interface, which then does something like

              value = library.value()
              self.dialog.setValue(value)
              

              Unless your "library" is also a Qt module, it makes no sense for the library to know about any UI elements or what is done with the results later... and even then it's bad in most cases.
              ( -> Backend/Frontend)


              If debugging is the process of removing software bugs, then programming must be the process of putting them in.

              ~E. W. Dijkstra

              E 1 Reply Last reply
              1
              • Pl45m4P Pl45m4

                @explorer100 said in forcing update of dialog:

                I suppose the dialog could pass its' "self" to the library and the library would call its update function. which in tern would update the progress bars?

                No, as I've said before, why do you want to pass your GUI elements around for them to receive their updates elsewhere?!
                Whether you pass the whole dialog or just the progressbar makes no difference designwise.
                Depends on what type of library you have and its purpose. If it's solely for doing some tasks in the background, it should not access the GUI directly.
                If your dialog should display the progress of some calculations made in your library, then send the update (the values) to your main GUI interface, which then does something like

                value = library.value()
                self.dialog.setValue(value)
                

                Unless your "library" is also a Qt module, it makes no sense for the library to know about any UI elements or what is done with the results later... and even then it's bad in most cases.
                ( -> Backend/Frontend)

                E Offline
                E Offline
                explorer100
                wrote on last edited by explorer100
                #11

                @Pl45m4 Do mean pass for example the MainWindow (self.super in the case of the dialog in question) to the library?
                then the main window will call the dialog's update function?

                1 Reply Last reply
                0
                • SGaistS Offline
                  SGaistS Offline
                  SGaist
                  Lifetime Qt Champion
                  wrote on last edited by
                  #12

                  Hi,

                  No, your library should not care at all about anything UI related. Just make it provide these values and then connect your UI to them.

                  If it's a Qt based library, use signals and slots.

                  Interested in AI ? www.idiap.ch
                  Please read the Qt Code of Conduct - https://forum.qt.io/topic/113070/qt-code-of-conduct

                  E 1 Reply Last reply
                  1
                  • SGaistS SGaist

                    Hi,

                    No, your library should not care at all about anything UI related. Just make it provide these values and then connect your UI to them.

                    If it's a Qt based library, use signals and slots.

                    E Offline
                    E Offline
                    explorer100
                    wrote on last edited by explorer100
                    #13

                    @SGaist it is not qt based library. I suppose I could pass the library a callable (basically that would act as a slot).. say progress_changed() callable in the dialog. The callable would then query the library of its progress and alter the dialog accordingly.

                    What is happening now is the progress bars as sent to the library as objects and the library calls their setValue().

                    1 Reply Last reply
                    0
                    • JonBJ Offline
                      JonBJ Offline
                      JonB
                      wrote on last edited by
                      #14

                      That sounds better. Provide a callable of your own to the library, in your own code you can do whatever in the UI. Don't directly pass a Qt widget or slot or anything which allows access to the UI.

                      If the library itself does not offer to call some function every so often with its progress as a parameter and instead you have to query its progress you will have to do so on a timer with some appropriate frequency.

                      The repaint worked beautifully as it updated the dialog from an external process where the update immediately displayed on the dialog while the rest of the program proceeded to do some calculation heavy activities (update() didn't work).

                      The point is that you ought not have to repaint() explicitly. If the "rest of the program" has to do a time-consuming computation and you do that from the main/UI thread your UI will "block"/"freeze", and that is not good for the user. Then you should run the computation --- which might be the library code --- in its own thread. That will allow the UI to remain responsive to the user and should mean you would not need to repaint() as the event loop will be able to process updates.

                      E 1 Reply Last reply
                      1
                      • JonBJ JonB

                        That sounds better. Provide a callable of your own to the library, in your own code you can do whatever in the UI. Don't directly pass a Qt widget or slot or anything which allows access to the UI.

                        If the library itself does not offer to call some function every so often with its progress as a parameter and instead you have to query its progress you will have to do so on a timer with some appropriate frequency.

                        The repaint worked beautifully as it updated the dialog from an external process where the update immediately displayed on the dialog while the rest of the program proceeded to do some calculation heavy activities (update() didn't work).

                        The point is that you ought not have to repaint() explicitly. If the "rest of the program" has to do a time-consuming computation and you do that from the main/UI thread your UI will "block"/"freeze", and that is not good for the user. Then you should run the computation --- which might be the library code --- in its own thread. That will allow the UI to remain responsive to the user and should mean you would not need to repaint() as the event loop will be able to process updates.

                        E Offline
                        E Offline
                        explorer100
                        wrote on last edited by explorer100
                        #15

                        @JonB I fully agree with you on this. That is happening now (1-2 minutes of frozen ui until the library finishes with its calculations).
                        Will pursue the multi-thread approach. Although, in this case, what the libraries are calculating will have major impact on all the dialogs which will be refreshed after the calculations finish. So blocking, in this case is actually desired as long as I can show progress in real time of the library calculations,

                        JonBJ 1 Reply Last reply
                        0
                        • E explorer100

                          @JonB I fully agree with you on this. That is happening now (1-2 minutes of frozen ui until the library finishes with its calculations).
                          Will pursue the multi-thread approach. Although, in this case, what the libraries are calculating will have major impact on all the dialogs which will be refreshed after the calculations finish. So blocking, in this case is actually desired as long as I can show progress in real time of the library calculations,

                          JonBJ Offline
                          JonBJ Offline
                          JonB
                          wrote on last edited by JonB
                          #16

                          @explorer100
                          Be sure to keep the main/UI thread quite separate from the computation thread, which should not try to do anything to the UI. As far as possible do not attempt to share any variables. Use Qt signals and slots for communication between the two threads, e.g. UI thread sends a signal when computation should start, computation thread send a signal when it has calculated something. Follow the worker object pattern in the first code block at https://doc.qt.io/qt-6/qthread.html#details.

                          E 1 Reply Last reply
                          0
                          • JonBJ JonB

                            @explorer100
                            Be sure to keep the main/UI thread quite separate from the computation thread, which should not try to do anything to the UI. As far as possible do not attempt to share any variables. Use Qt signals and slots for communication between the two threads, e.g. UI thread sends a signal when computation should start, computation thread send a signal when it has calculated something. Follow the worker object pattern in the first code block at https://doc.qt.io/qt-6/qthread.html#details.

                            E Offline
                            E Offline
                            explorer100
                            wrote on last edited by
                            #17

                            @JonB Thank you for the advice. much appreciated. but given that blocking is desired in this case. (as the results of the library calculations will affect all the dialogs) would the callable approach be sufficient? or would you still suggest threading?

                            Pl45m4P 1 Reply Last reply
                            0
                            • E explorer100

                              @JonB Thank you for the advice. much appreciated. but given that blocking is desired in this case. (as the results of the library calculations will affect all the dialogs) would the callable approach be sufficient? or would you still suggest threading?

                              Pl45m4P Offline
                              Pl45m4P Offline
                              Pl45m4
                              wrote on last edited by Pl45m4
                              #18

                              @explorer100 said in forcing update of dialog:

                              but given that blocking is desired in this case. (as the results of the library calculations will affect all the dialogs)

                              Blocking the UI thread in a GUI app is never desirable.
                              The app seems to be not responsive to the user, well, because it actually is not responding anymore, and might crash through random and undefined user input.
                              You need to take care of handling tasks which might take longer time yourself (UX is the keyword).
                              There are couple things you can do... Busy notifications, progress bars etc.

                              You need something that indicates that the task is running, but still takes some time to finish.
                              Without blocking the Qt event loop!!
                              A blocking progress bar makes no sense, since it would start, block, finish the task and then the UI would receive updates again causing the progress to jump from 0 to 100, if something like that even happens... maybe you don't see anything.

                              See "the dumb approach" here

                              This could work for you:

                              • https://doc.qt.io/qtforpython-6/overviews/qtconcurrentrun.html#progress-reporting

                              If debugging is the process of removing software bugs, then programming must be the process of putting them in.

                              ~E. W. Dijkstra

                              E 1 Reply Last reply
                              1
                              • Pl45m4P Pl45m4

                                @explorer100 said in forcing update of dialog:

                                but given that blocking is desired in this case. (as the results of the library calculations will affect all the dialogs)

                                Blocking the UI thread in a GUI app is never desirable.
                                The app seems to be not responsive to the user, well, because it actually is not responding anymore, and might crash through random and undefined user input.
                                You need to take care of handling tasks which might take longer time yourself (UX is the keyword).
                                There are couple things you can do... Busy notifications, progress bars etc.

                                You need something that indicates that the task is running, but still takes some time to finish.
                                Without blocking the Qt event loop!!
                                A blocking progress bar makes no sense, since it would start, block, finish the task and then the UI would receive updates again causing the progress to jump from 0 to 100, if something like that even happens... maybe you don't see anything.

                                See "the dumb approach" here

                                This could work for you:

                                • https://doc.qt.io/qtforpython-6/overviews/qtconcurrentrun.html#progress-reporting
                                E Offline
                                E Offline
                                explorer100
                                wrote on last edited by
                                #19

                                @Pl45m4

                                Thank you very much for the advice of:

                                • list itemhttps://doc.qt.io/qtforpython-6/overviews/qtconcurrentrun.html#progress-reporting

                                Also JonB recommended:

                                • list itemFollow the worker object pattern in the first code block at https://doc.qt.io/qt-6/qthread.html#details.

                                I will look up both... it seems the first approach may be simpler to implement? Any advice? Thanks again!

                                1 Reply Last reply
                                0
                                • E explorer100

                                  The repaint worked beautifully as it updated the dialog from an external process where the update immediately displayed on the dialog while the rest of the program proceeded to do some calculation heavy activities (update() didn't work).

                                  I looked around to see what issues to look out for when using repaint() but did not find any info. I would appreciate any info on this.

                                  On a related note: I have a dialog that passes its progress bars to a library outside the dialog which in-tern updates the value of each of the progress bars (from the external library). It all works well as the progress bars change showing the progress in real time of the library functions (percent completions).

                                  But when some window is moved on top of this dialg then moved back, the dialog no longer shows any changes untill the library completes all its processing.

                                  Is there a way to circumvent this issue? I suppose the library can repaint() the progress bars?

                                  S Offline
                                  S Offline
                                  SimonSchroeder
                                  wrote on last edited by
                                  #20

                                  @explorer100 said in forcing update of dialog:

                                  I looked around to see what issues to look out for when using repaint() but did not find any info. I would appreciate any info on this.

                                  General advice is to never use repaint() (unless you really have to). You code might be changing many things inside a UI; much faster than the refresh rate of your display. If you are calling repaint() after every little change, your application might get really slow as it has to do too much unnecessary work. Instead you should always be calling update() instead. It will first gather multiple update calls and issue a single repaint for them. This has much better performance. However, update() only works while the event loop is not blocked. repaint() on the other hand can use a direct call in case it is running in the GUI thread and thus bypass the event loop (which is happening in your place).

                                  Traditionally, people use QApplication::processEvents() to help a progress bar to process updates (it will just process everything that was still left in the event queue). However, this also has really bad performance and should really be avoided. Furthermore, it would keep the whole GUI functioning (with maybe some intermittend freezing) in the same way as it has already been suggested with threads (I agree to use a worker thread to keep the GUI running). The solution to this is making your progress dialog modal such that the user cannot interact with the rest of the GUI.

                                  The cleanest software engineering solution for updating the progress bar from your worker thread would be to use signals and slots. However, as you have said, your own library is not Qt (but you pull in that dependency by calling setValue directly from your library code). A callback function would be most flexible and would decouple your library from Qt entirely. I personally don't write a signal to be called by the callback, but would directly post an event to the GUI loop: QMetaObject::invokeMethod(qApp, [&progressDialog](int progress) { progressDialog->setValue(progress); }, progress);

                                  1 Reply Last reply
                                  0

                                  • Login

                                  • Login or register to search.
                                  • First post
                                    Last post
                                  0
                                  • Categories
                                  • Recent
                                  • Tags
                                  • Popular
                                  • Users
                                  • Groups
                                  • Search
                                  • Get Qt Extensions
                                  • Unsolved