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 explorer100
    #1

    Hello,

    I have a dialog that is visible in show() mode and is not Modal.
    Is there a way to change one of its widgets from outside the dialog and have the change display in the dialog immediately while the rest of the system is still running?

    Now the change in the dialog only becomes visible when the rest of the system is not in wait state.

    Thank you.

    Pl45m4P jsulmJ JonBJ 3 Replies Last reply
    0
    • E explorer100

      Hello,

      I have a dialog that is visible in show() mode and is not Modal.
      Is there a way to change one of its widgets from outside the dialog and have the change display in the dialog immediately while the rest of the system is still running?

      Now the change in the dialog only becomes visible when the rest of the system is not in wait state.

      Thank you.

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

      @explorer100 said in forcing update of dialog:

      Is there a way to change one of its widgets from outside the dialog and have the change display in the dialog immediately while the rest of the system is still running?

      Change in what way? What are you planning to change?

      I have a dialog that is visible in show() mode and is not Modal.

      Because you show() it as non-modal dialog/widget, it does not have it's own event-loop.
      So treat it as you would treat any other QWidget type...

      Now the change in the dialog only becomes visible when the rest of the system is not in wait state.

      How do you update or change your dialog currently?
      What wait state? Are you blocking the app with your dialog?! A non-modal dialog should not do this.


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

      ~E. W. Dijkstra

      1 Reply Last reply
      1
      • E explorer100

        Hello,

        I have a dialog that is visible in show() mode and is not Modal.
        Is there a way to change one of its widgets from outside the dialog and have the change display in the dialog immediately while the rest of the system is still running?

        Now the change in the dialog only becomes visible when the rest of the system is not in wait state.

        Thank you.

        jsulmJ Offline
        jsulmJ Offline
        jsulm
        Lifetime Qt Champion
        wrote on last edited by
        #3

        @explorer100 said in forcing update of dialog:

        Now the change in the dialog only becomes visible when the rest of the system is not in wait state

        Wait state? What you describe sounds rather like you're blocking the event loop. As long as the event loop is blocked nothing will be updated in the UI. But without more information, or better code, we can just guess.

        https://forum.qt.io/topic/113070/qt-code-of-conduct

        1 Reply Last reply
        0
        • E explorer100

          Hello,

          I have a dialog that is visible in show() mode and is not Modal.
          Is there a way to change one of its widgets from outside the dialog and have the change display in the dialog immediately while the rest of the system is still running?

          Now the change in the dialog only becomes visible when the rest of the system is not in wait state.

          Thank you.

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

          @explorer100 said in forcing update of dialog:

          have the change display in the dialog immediately

          Now the change in the dialog only becomes visible when the rest of the system is not in wait state.

          Outside of the issue of whether you might be blocking the event loop. Immediately after you alter a widget from outside the dialog (dialogInstance.label.setText() or whatever) first try dialogInstance.label.update() and if that does not update immediately try dialogInstance.label.repaint(). Which is not always desirable but should allow immediate update/repaint when the event loop is not available to process paintEvents.

          1 Reply Last reply
          0
          • 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