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. Minimal requirement to update a QLabel's text and show it
Forum Updated to NodeBB v4.3 + New Features

Minimal requirement to update a QLabel's text and show it

Scheduled Pinned Locked Moved Solved General and Desktop
22 Posts 4 Posters 9.7k Views 2 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.
  • SGaistS Offline
    SGaistS Offline
    SGaist
    Lifetime Qt Champion
    wrote on last edited by
    #12

    If you don't want any event to be handle by the QApplication instance, then you have to do the same things a QProgressDialog: spin your own event loop.

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

    JonBJ 1 Reply Last reply
    0
    • SGaistS SGaist

      If you don't want any event to be handle by the QApplication instance, then you have to do the same things a QProgressDialog: spin your own event loop.

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

      @SGaist , or whoever,

      OK, there is something "magic" about QProgressBar which differs from QLabel, and I need someone to explain what it is, please. Basically, a QProgressBar updates visually without my needing to call QApplication::processEvents() but a QLabel does not.

      Consider the following sample, skeleton code:
      Main program:

      if __name__ == '__main__':
          app = QtWidgets.QApplication(sys.argv)
      
          main = Main()
      
          sys.exit(app.exec_())
      

      Main function:

      class Main(QtWidgets.QMainWindow):
          def __init__(self):
              super().__init__()
      
              self.setWindowTitle("Main")
              self.setGeometry(100, 100, 500, 500)
      
              self.centralWidget = QtWidgets.QWidget(self)
              self.setCentralWidget(self.centralWidget)
              self.centralLayout = QtWidgets.QHBoxLayout(self.centralWidget)
      
              self.lblPb = QtWidgets.QLabel()
              self.centralLayout.addWidget(self.lblPb)
              self.lblPb.setText("Initial")
      
              self.pb = QtWidgets.QProgressBar()
              self.centralLayout.addWidget(self.pb)
              self.pb.setRange(0, 10)
              self.pb.setValue(0)
      
              self.show()
      
              QtCore.QTimer.singleShot(1000, self.doProgress)
      

      doProgress() function:

          def doProgress(self):
              import time
              for i in range(10 + 1):
                  # update the label text
                  self.lblPb.setText(str(i))
      
                  # We need *one* of the next two lines
                  # to see the updated label text from above
                  self.pb.setValue(i)
                  # QApplication::processEvents()
      
                  # Yes, the next line is *deliberately* a "sleep"
                  # It *simulates* doing some processing but *not* calling `processEvents()`
                  time.sleep(1)
      

      So, I'm just setting off to call doProgress() after the main window is up & shown. Its job is to update the QProgressBar and the QLabel while in a non-event-processing-loop, to see what is visible.

      Now, what is interesting is that the progressive QLabel.setText() is only visible because we are also calling QProgressBar.setValue(). The progress bar gets visually updated, and so does the label text. But if we remove the call to QProgressBar.setValue() we do not see the label updating. We then have to put in an explicit QApplication::processEvents() to get to see the label's new value.

      So: what is QProgressBar.setValue() doing exactly to cause this, and where is that documented, please, please?

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

        Ah ha!!!

        Googling around, I have come across QWidget::repaint(). After calling QLabel::setText(), I can just call QLabel::repaint() and I see the text immediately updated, just as wanted, without having to call QApplication::processEvents() or QProgressBar.setValue().

        I'd still like to know what QProgressBar.setValue() does to allow the QLabel to repaint too, but I seem to have my solution.

        May I ask: I kept asking "how can I force widget repaint without processing events", and nobody drew my attention to QWidget::repaint(). Why is that, please?

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

          Nothing against you, I worked from memory and I had forgotten about the specifics of repaint well update VS repaint.

          What QProgressBar does is that it check if it needs to repaint based on internal logic and calls repaint if it turns out to be the case.

          Just in case, don't forget the warning and recommendation in the repaint documentation.

          Thanks for the reminder :)

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

          JonBJ 1 Reply Last reply
          1
          • SGaistS SGaist

            Nothing against you, I worked from memory and I had forgotten about the specifics of repaint well update VS repaint.

            What QProgressBar does is that it check if it needs to repaint based on internal logic and calls repaint if it turns out to be the case.

            Just in case, don't forget the warning and recommendation in the repaint documentation.

            Thanks for the reminder :)

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

            @SGaist
            Thanks, no problem. I trust you to be a guru :) I just had to understand why I was hitting my head against a brick wall, I believed there just had to be some kind of "repaint now, don't wait for event loop".

            It seems to be ideal for my "force update of text while doing other stuff". Just like the docs say, and yes I am aware of recursion and no I won't be inside another paintEvent!

            For the record, QProgressBar.setValue() must do more than just "repaint itself" (e.g. by calling repaint()). My point is, when I call QProgressBar.setValue() in addition to seeing the progressbar repaint I also see the unrelated QLabel repaint. So it must actually/presumably be doing some kind of processEvents(), allowing other widgets to paint etc. too. It's easy for me to say this, but I'd really like to see the setValue() docs have something to say about this immediate repaint/process events behaviour, as it's "unique" to QProgressBar and can be very relevant... (I know, I know, I need to start getting into raising Qt docs requests!)

            Meanwhile I've got what I need, and I (more or less) understand what's going on, so thank you.

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

              To update, say, a QLabel's text immediately so that it's shown to the user, without waiting for the main event loop to be re-entered or writing an explicit QApplication::processEvents(), turns out all you have to do is call QWidget::repaint().

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

                It doesn't, widgets are only responsible for dealing with their own updates, as for what happens to their parents, it's not them to decide. You can see the setValue implementation here.

                What you can also do is submit fixes for the documentation to make it clearer :)

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

                JonBJ 1 Reply Last reply
                0
                • SGaistS SGaist

                  It doesn't, widgets are only responsible for dealing with their own updates, as for what happens to their parents, it's not them to decide. You can see the setValue implementation here.

                  What you can also do is submit fixes for the documentation to make it clearer :)

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

                  @SGaist

                  It doesn't

                  Now we have a problem! Because I have posted code above which demonstrates that calling QProgressBar.setValue() not only paints itself but also causes my unrelated QLabel to get repainted. If I take out the QProgressBar.setValue() then I have to call either QApplication::processEvents() or QLabel::repaint() to see the altered text in the QLabel. So how do you explain that?? :) I agree I can't see much in the QProgressBar.setValue(), but I've given the code above from a test I did, so what's causing the QLabel to repaint when all I do is call QProgressBar.setValue()?!

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

                    My point was that QProgressBar doesn't do anything special with regard to other widgets surrounding it (as you saw from its implementation). It's a border effect, nice in your case, but I wouldn't rely on it.

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

                    JonBJ 1 Reply Last reply
                    0
                    • SGaistS SGaist

                      My point was that QProgressBar doesn't do anything special with regard to other widgets surrounding it (as you saw from its implementation). It's a border effect, nice in your case, but I wouldn't rely on it.

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

                      @SGaist said in Minimal requirement to update a QLabel's text and show it:

                      It's a border effect

                      What does that mean? Are you saying something like: the QProgressBar::repaint() call (in QProgressBar.setValue()) just happens to cause the QLabel to repaint because the widgets are close to each other, there is some overlap?

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

                        From a quick look, it goes down to the rendering engine, I haven't read the whole implementation to determine exactly how the repainting of one of the widget triggers an update of the whole "container" widget.

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

                        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