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. QWidget paint event draw over children
Forum Update on Monday, May 27th 2025

QWidget paint event draw over children

Scheduled Pinned Locked Moved Unsolved General and Desktop
qwidgetpaint event
7 Posts 3 Posters 10.8k 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.
  • Joel BodenmannJ Offline
    Joel BodenmannJ Offline
    Joel Bodenmann
    wrote on last edited by
    #1

    I have a custom subclass of QTabWidget. The tab widget contains QTextEdit widgets as children. I would like to render rectangles on the side of my tab widget to indicate when a drop action is possible. For that purpose, I overwrite the QTabWidget::paintEvent() function:

    void TabWidget::paintEvent(QPaintEvent* event)
    {
        // Default rendered
        QTabWidget::paintEvent(event);
    
        // Render the drop zone rect (if any)
        if (!_dropZoneRect.isNull()) {
            QPainter painter(this);
    
            painter.setPen(Qt::NoPen);
            painter.setBrush(QBrush(Qt::lightGray));
            painter.drawRect(_dropZoneRect);
        }
    }
    

    The problem that I am facing is that it appears that the children of the tab widget are getting painted AFTER the TabWidget::paintEvent() function has been called. Therefore, I see my rectangle around the border of the TabWidget but the QTextEdit children are painted above that.
    How can I paint something above my custom QTabWidget so that it covers the child widget too?

    Thanks for the help.

    Industrial process automation software: https://simulton.com
    Embedded Graphics & GUI library: https://ugfx.io

    1 Reply Last reply
    0
    • Chris KawaC Offline
      Chris KawaC Offline
      Chris Kawa
      Lifetime Qt Champion
      wrote on last edited by
      #2

      There's no way to paint over child widgets in the parent class (that I know of). You would need an "overlay" widget i.e. a widget that is positioned exactly above your tab widget and draw the rectangle there (something like what QRubberBand does). Since you use it only while a drag is happening it shouldn't be a problem. No need to worry about resizing and other events since a drag is happening.

      Joel BodenmannJ 2 Replies Last reply
      1
      • Chris KawaC Chris Kawa

        There's no way to paint over child widgets in the parent class (that I know of). You would need an "overlay" widget i.e. a widget that is positioned exactly above your tab widget and draw the rectangle there (something like what QRubberBand does). Since you use it only while a drag is happening it shouldn't be a problem. No need to worry about resizing and other events since a drag is happening.

        Joel BodenmannJ Offline
        Joel BodenmannJ Offline
        Joel Bodenmann
        wrote on last edited by Joel Bodenmann
        #3

        Well that's unexpected...
        May I ask what the reason for this behavior is? I would have expected that the QTabWidget::paintEvent() renders the tab widget and it's children and after that I can perform my drawing operation which will (obviously?) occur above what has been drawn before.

        Anyway, I got it doing what I want it to do by following your advice of rendering a widget on top of the tab widget. For some reason I don't like this solution but as long as that is the way that I am supposed to do it I can life with it :)

        Industrial process automation software: https://simulton.com
        Embedded Graphics & GUI library: https://ugfx.io

        kshegunovK 1 Reply Last reply
        0
        • Joel BodenmannJ Joel Bodenmann

          Well that's unexpected...
          May I ask what the reason for this behavior is? I would have expected that the QTabWidget::paintEvent() renders the tab widget and it's children and after that I can perform my drawing operation which will (obviously?) occur above what has been drawn before.

          Anyway, I got it doing what I want it to do by following your advice of rendering a widget on top of the tab widget. For some reason I don't like this solution but as long as that is the way that I am supposed to do it I can life with it :)

          kshegunovK Offline
          kshegunovK Offline
          kshegunov
          Moderators
          wrote on last edited by
          #4

          @Joel-Bodenmann said:

          May I ask what the reason for this behavior is?

          This might be answered by the developers, I for one don't know the internals so well. I would assume that the paint event is sent only to the relevant widgets (based on geometry) for performance (e.g. you don't need to repaint widgets that hadn't been obscured by other windows and then exposed).

          I would have expected that the QTabWidget::paintEvent() renders the tab widget and it's children and after that I can perform my drawing operation which will (obviously?) occur above what has been drawn before.

          QTabWidget::paintEvent paints only the tab bar, not the children it contains. But in any case I don't know of a widget that explicitly repaints it children. I believe Qt sends the appropriate paint events to all affected widgets based on their geometry (i.e. depending on the "dirty" region).

          Kind regards.

          Read and abide by the Qt Code of Conduct

          Joel BodenmannJ 1 Reply Last reply
          2
          • kshegunovK kshegunov

            @Joel-Bodenmann said:

            May I ask what the reason for this behavior is?

            This might be answered by the developers, I for one don't know the internals so well. I would assume that the paint event is sent only to the relevant widgets (based on geometry) for performance (e.g. you don't need to repaint widgets that hadn't been obscured by other windows and then exposed).

            I would have expected that the QTabWidget::paintEvent() renders the tab widget and it's children and after that I can perform my drawing operation which will (obviously?) occur above what has been drawn before.

            QTabWidget::paintEvent paints only the tab bar, not the children it contains. But in any case I don't know of a widget that explicitly repaints it children. I believe Qt sends the appropriate paint events to all affected widgets based on their geometry (i.e. depending on the "dirty" region).

            Kind regards.

            Joel BodenmannJ Offline
            Joel BodenmannJ Offline
            Joel Bodenmann
            wrote on last edited by
            #5

            @kshegunov Thank you for the information. Much appreciated!

            Industrial process automation software: https://simulton.com
            Embedded Graphics & GUI library: https://ugfx.io

            kshegunovK 1 Reply Last reply
            0
            • Joel BodenmannJ Joel Bodenmann

              @kshegunov Thank you for the information. Much appreciated!

              kshegunovK Offline
              kshegunovK Offline
              kshegunov
              Moderators
              wrote on last edited by
              #6

              @Joel-Bodenmann
              Well, it's mostly speculation, but you're welcome. :)

              Read and abide by the Qt Code of Conduct

              1 Reply Last reply
              0
              • Chris KawaC Chris Kawa

                There's no way to paint over child widgets in the parent class (that I know of). You would need an "overlay" widget i.e. a widget that is positioned exactly above your tab widget and draw the rectangle there (something like what QRubberBand does). Since you use it only while a drag is happening it shouldn't be a problem. No need to worry about resizing and other events since a drag is happening.

                Joel BodenmannJ Offline
                Joel BodenmannJ Offline
                Joel Bodenmann
                wrote on last edited by
                #7

                @Chris-Kawa It turned out that QRubberBand is EXACTLY what I wanted. I am now using that successfully to display the drop zones. Thank you for introducing me to that :)

                Industrial process automation software: https://simulton.com
                Embedded Graphics & GUI library: https://ugfx.io

                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