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. Update / repaint a QWidget while it is hidden

Update / repaint a QWidget while it is hidden

Scheduled Pinned Locked Moved Solved General and Desktop
5 Posts 2 Posters 3.1k Views
  • 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.
  • S Offline
    S Offline
    Sylve
    wrote on last edited by Sylve
    #1

    Hello,

    Edit: see my last post (#4) for a detailed description of my problem.

    I have a very simple question.

    The repaint() and update() method can be called (effectively triggering at some point a paintEvent) when a QWidget is visible, see https://doc.qt.io/qt-5/qwidget.html#repaint and https://doc.qt.io/qt-5/qwidget.html#update .

    My question is the following: how can I "repaint" (i.e. trigger a call to paintEvent) while my widget is hidden?

    I have a widget I do some processing on while it is hidden, and I would like those modifications to be already there when I call show(). Currently, I have maybe 30 ms where the modifications (text, size, etc.) are processed, and this is unfortunately visible and ugly (inbetween the call to show() and the call to paintEvent).

    I can try to provide a minimal example if this is useful.

    Thanks a lot!

    1 Reply Last reply
    0
    • Christian EhrlicherC Offline
      Christian EhrlicherC Offline
      Christian Ehrlicher
      Lifetime Qt Champion
      wrote on last edited by
      #2

      A hidden widget is not painted. If your repaint takes so long I would consider moving the painting to a separate thread on a QImage and then only paint this image in the paint event.

      Qt Online Installer direct download: https://download.qt.io/official_releases/online_installers/
      Visit the Qt Academy at https://academy.qt.io/catalog

      1 Reply Last reply
      1
      • S Offline
        S Offline
        Sylve
        wrote on last edited by Sylve
        #3

        Here is a log of the event triggered to be a bit clearer. In my case, I have a QFrame which is the parent of a QTextEdit.

        In the order, here is what is happening:

        /* I call a update function, and call hide() on the QFrame because I want nothing to be shown during those modifications*/
        QFrame: PySide6.QtCore.QEvent.Type.Hide
        QTextEdit: PySide6.QtCore.QEvent.Type.Hide
        QFrame: PySide6.QtCore.QEvent.Type.HideToParent
        /* Some modifications to the content, position and size of the QFrame and QTextEdit, through move, updateGeometry, resize, and e.g. setText */
        /* After those modifications, I trigger self.show() on the parent QFrame */
        /* Then, AFTER the show(), the event calls are the following: */
        QFrame: PySide6.QtCore.QEvent.Type.Move
        QFrame: PySide6.QtCore.QEvent.Type.Resize
        QTextEdit: PySide6.QtCore.QEvent.Type.Resize
        QTextEdit: PySide6.QtCore.QEvent.Type.Show
        QFrame: PySide6.QtCore.QEvent.Type.Show
        QFrame: PySide6.QtCore.QEvent.Type.ShowToParent
        /* The problem is in the following paint call. If my paintEvent for my QTextEdit is slow, then the window will be resized and STILL show the previous text which is unwanted. */
        QFrame: PySide6.QtCore.QEvent.Type.Paint
        QTextEdit: PySide6.QtCore.QEvent.Type.Paint
        QTextEdit: PySide6.QtCore.QEvent.Type.MetaCall
        QTextEdit: PySide6.QtCore.QEvent.Type.UpdateLater
        QFrame: PySide6.QtCore.QEvent.Type.UpdateLater
        QFrame: PySide6.QtCore.QEvent.Type.UpdateRequest
        /* For some reason it is only at this call that the new text is printed. */
        QFrame: PySide6.QtCore.QEvent.Type.Paint
        QTextEdit: PySide6.QtCore.QEvent.Type.Paint
        

        What I would like to have, is everything shown when the update is finished, and only then.

        Edit:

        Thanks a lot for your answer @Christian-Ehrlicher . Do you think this would be doable for text? I need it to be selectable so it is likely that as an image would be difficult, I would guess.

        To elaborate a bit, I am building a tool for subtitles, and at subtitle change there is an extremely small flickering (but still visible) when the subtitle changes. Basically, something is messed up with the resize and setting new text, and there is maybe 50 ms during which painting and resizing occurs, which is undesirable. I have tried to identify the issue putting some time.sleep(), and that is how I cam up with the log above.

        Edit2: Anyway I am ready to put a bounty on this to anyone who can guide to solve it. Please PM me.

        1 Reply Last reply
        0
        • S Offline
          S Offline
          Sylve
          wrote on last edited by Sylve
          #4

          Here is a minimal reproducible example: https://pastebin.com/QNxKXQ10

          This corresponding video illustrates the result from running the code: https://www.youtube.com/watch?v=pibdxKgbFjw

          To explain again:
          We have a QFrame containing a QTextEdit in its layout.
          We call twice the function render_subtitles, first with the text My first long sub, for example..., and then a bit later with the text Shorter one! (handled in a thread).

          This render_subtitles is responsible for clearing the old content of the QTextEdit, putting the new text, resizing and placing at the right place the QFrame and its child QTextEdit.

          I have put a time.sleep() in the paintEvent from each of the QFrame and QTextEdit, to illustrate better my case (otherwise it is like 50 ms only).

          Basically, in the video, we see that the resizing happens BEFORE the new text appears (and that the old text is still there!). I would like the resizing and the change of text to happen simultaneously, no matter how long paintEvent takes. Then, I would like to show those changes.

          1 Reply Last reply
          0
          • S Offline
            S Offline
            Sylve
            wrote on last edited by
            #5

            This is solved using self.subtext.repaint() right after the clear() for the QTextEdit, as well as with using a key indicating whether or not the update is finished. We test this key in the paintEvent of the QFrame to effectively paint the new background only when everything is ready.

            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