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 with graphicseffect and render method
Forum Updated to NodeBB v4.3 + New Features

QWidget with graphicseffect and render method

Scheduled Pinned Locked Moved Unsolved General and Desktop
4 Posts 2 Posters 81 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.
  • D Offline
    D Offline
    denistu
    wrote last edited by
    #1

    I've got problem when using QWidget::render method to draw widget to pixmap.
    If QWidget has no graphicseffect, then everething is ok.
    But if I apply graphicseffect (QGraphicsDropShadowEffect), then QWidget::render draws nothing.
    I have to call QWidget::graphicsEffect()::setEnabled(false), then QWidget::render, then QWidget::graphicsEffect()::setEnabled(true).
    Is there a way to use QWidget::render with graphicseffect, without turning it off? Or any clues to find out root cause of my problem?
    Qt 5.15, windows environment.

    1 Reply Last reply
    0
    • HansonH Offline
      HansonH Offline
      Hanson
      wrote last edited by
      #2

      @denistu Hi
      You can use QScreen::grabWindow()

      QGuiApplication::primaryScreen()->grabWindow(winId()).save("screenScreenshot.png");
      

      From QScreen::grabWindow() documentation:

      The grabWindow() function grabs pixels from the screen, not from the window, i.e. if there is another window partially or entirely over the one you grab, you get pixels from the overlying window, too.
      https://doc.qt.io/qt-6/qscreen.html#grabWindow

      “Always code as if the guy who ends up maintaining your code will be a violent psychopath who knows where you live.”
      —— Martin Golding

      1 Reply Last reply
      0
      • D Offline
        D Offline
        denistu
        wrote last edited by
        #3

        thanks for reply, but QScreen::grabWindow is unacceptable, because of resolution.
        In my case window is often has less resolution than pixmap I'm rendering to.
        Resulting pixmap must be of original resolution, FulllHD, 4k or more.

        1 Reply Last reply
        0
        • HansonH Offline
          HansonH Offline
          Hanson
          wrote last edited by Hanson
          #4

          @denistu
          After I read the source code, I found that when a widget with QGraphicsEffect executes the render method, the internal call to QGraphicsEffect's draw method will call the sourceWidget's render method again. However, there's an internal judgment in the render method that causes the sourceWidget to return. So, you can see that using the target widget's render method directly doesn't work. So, all we have to do is figure out a way to call the widget's render method indirectly.We can set a container widget as the parent widget for the widget and just call the container widget's render method. That'll execute the render methods of all child widgets.I hope this helps.

          void QWidget::render(QPainter *painter, const QPoint &targetOffset,
                               const QRegion &sourceRegion, RenderFlags renderFlags)
          {
          ....
              Q_D(QWidget);
              const bool inRenderWithPainter = d->extra && d->extra->inRenderWithPainter;
              const QRegion toBePainted = !inRenderWithPainter ? d->prepareToRender(sourceRegion, renderFlags)
                                                               : sourceRegion;
              if (toBePainted.isEmpty())
                  return;
          
              if (!d->extra)
                  d->createExtra();
              d->extra->inRenderWithPainter = true;
          ....
          }
          

          https://code.qt.io/cgit/qt/qtbase.git/tree/src/widgets/kernel/qwidget.cpp#n5316

          QPixmap QWidgetEffectSourcePrivate::pixmap(Qt::CoordinateSystem system, QPoint *offset,
                                                     QGraphicsEffect::PixmapPadMode mode) const
          {
          ....
          // call render() again, so would retrun and the pixmap is  only transpant with nothings.
          m_widget->render(&pixmap, pixmapOffset, QRegion(), QWidget::DrawChildren);
          ....
          }
          

          https://code.qt.io/cgit/qt/qtbase.git/tree/src/widgets/kernel/qwidget.cpp#n6040

          “Always code as if the guy who ends up maintaining your code will be a violent psychopath who knows where you live.”
          —— Martin Golding

          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