From cfc94db49fbcb1913a546784536c742b353b9391 Mon Sep 17 00:00:00 2001 From: Friedemann Kleint Date: Fri, 29 Jul 2011 13:47:23 +0200 Subject: Bring back QPixmap::grabWidget() (with a warning). MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Change-Id: I8bbf07da474bc3ab35980b25c41c2fc4c02e8896 Reviewed-on: http://codereview.qt.nokia.com/2394 Reviewed-by: Qt Sanity Bot Reviewed-by: Samuel Rødal --- src/gui/image/qpixmap.cpp | 37 +++++++----------------------- src/gui/image/qpixmap.h | 4 ++-- src/widgets/kernel/qwidget.cpp | 52 ++++++++++++++++++++++++++++++++++++++++++ src/widgets/kernel/qwidget.h | 3 +++ 4 files changed, 65 insertions(+), 31 deletions(-) (limited to 'src') diff --git a/src/gui/image/qpixmap.cpp b/src/gui/image/qpixmap.cpp index af27baea0e..d02da27f4e 100644 --- a/src/gui/image/qpixmap.cpp +++ b/src/gui/image/qpixmap.cpp @@ -1029,39 +1029,18 @@ static void sendResizeEvents(QWidget *target) \sa grabWindow() */ -QPixmap QPixmap::grabWidget(QPaintDevice *, const QRect &) +QPixmap QPixmap::grabWidget(QObject *widget, const QRect &rectangle) { + QPixmap pixmap; // ### Qt5: should we keep or remove this method? // SC solution would be to install a callback form QtWidgets, but ugly. - qWarning() << "QPixmap::grabWidget is deprecated, use QWidget::render() instead"; - return QPixmap(); -#if 0 + qWarning("QPixmap::grabWidget is deprecated, use QWidget::grab() instead"); if (!widget) - return QPixmap(); - - if (widget->testAttribute(Qt::WA_PendingResizeEvent) || !widget->testAttribute(Qt::WA_WState_Created)) - sendResizeEvents(widget); - - widget->d_func()->prepareToRender(QRegion(), - QWidget::DrawWindowBackground | QWidget::DrawChildren | QWidget::IgnoreMask); - - QRect r(rect); - if (r.width() < 0) - r.setWidth(widget->width() - rect.x()); - if (r.height() < 0) - r.setHeight(widget->height() - rect.y()); - - if (!r.intersects(widget->rect())) - return QPixmap(); - - QPixmap res(r.size()); - if (!qt_widget_private(widget)->isOpaque) - res.fill(Qt::transparent); - - widget->d_func()->render(&res, QPoint(), r, QWidget::DrawWindowBackground - | QWidget::DrawChildren | QWidget::IgnoreMask, true); - return res; -#endif + return pixmap; + QMetaObject::invokeMethod(widget, "grab", Qt::DirectConnection, + Q_RETURN_ARG(QPixmap, pixmap), + Q_ARG(QRect, rectangle)); + return pixmap; } /*! diff --git a/src/gui/image/qpixmap.h b/src/gui/image/qpixmap.h index 66f1eda877..402708b48c 100644 --- a/src/gui/image/qpixmap.h +++ b/src/gui/image/qpixmap.h @@ -113,8 +113,8 @@ public: QBitmap createMaskFromColor(const QColor &maskColor, Qt::MaskMode mode = Qt::MaskInColor) const; static QPixmap grabWindow(WId, int x=0, int y=0, int w=-1, int h=-1); - static QPixmap grabWidget(QPaintDevice *widget, const QRect &rect); - static inline QPixmap grabWidget(QPaintDevice *widget, int x=0, int y=0, int w=-1, int h=-1) + static QPixmap grabWidget(QObject *widget, const QRect &rect); + static inline QPixmap grabWidget(QObject *widget, int x=0, int y=0, int w=-1, int h=-1) { return grabWidget(widget, QRect(x, y, w, h)); } inline QPixmap scaled(int w, int h, Qt::AspectRatioMode aspectMode = Qt::IgnoreAspectRatio, diff --git a/src/widgets/kernel/qwidget.cpp b/src/widgets/kernel/qwidget.cpp index d48d5ae15d..0e7a12c021 100644 --- a/src/widgets/kernel/qwidget.cpp +++ b/src/widgets/kernel/qwidget.cpp @@ -5150,6 +5150,58 @@ void QWidget::render(QPainter *painter, const QPoint &targetOffset, d->extra->inRenderWithPainter = false; } +static void sendResizeEvents(QWidget *target) +{ + QResizeEvent e(target->size(), QSize()); + QApplication::sendEvent(target, &e); + + const QObjectList children = target->children(); + for (int i = 0; i < children.size(); ++i) { + QWidget *child = static_cast(children.at(i)); + if (child->isWidgetType() && !child->isWindow() && child->testAttribute(Qt::WA_PendingResizeEvent)) + sendResizeEvents(child); + } +} + +/*! + \since 5.0 + + Renders the widget into a pixmap restricted by the + given \a rectangle. If the \a widget has any children, then + they are also painted in the appropriate positions. + + If no rectangle is specified (the default) the entire widget is + painted. + + Replacement for Qt 4's QPixmap::grabWidget(). + + \sa render(), QPixmap +*/ + +/* INVOKABLE since used by QPixmap::grabWidget(). */ +QPixmap QWidget::grab(const QRect &rectangle) +{ + Q_D(const QWidget); + if (testAttribute(Qt::WA_PendingResizeEvent) || !testAttribute(Qt::WA_WState_Created)) + sendResizeEvents(this); + + QRect r(rectangle); + if (r.width() < 0) + r.setWidth(width() - rectangle.x()); + if (r.height() < 0) + r.setHeight(height() - rectangle.y()); + + if (!r.intersects(rect())) + return QPixmap(); + + QPixmap res(r.size()); + if (!d->isOpaque) + res.fill(Qt::transparent); + render(&res, QPoint(), QRegion(r), QWidget::DrawWindowBackground + | QWidget::DrawChildren | QWidget::IgnoreMask); + return res; +} + /*! \brief The graphicsEffect function returns a pointer to the widget's graphics effect. diff --git a/src/widgets/kernel/qwidget.h b/src/widgets/kernel/qwidget.h index 755feb8849..65d5f4701c 100644 --- a/src/widgets/kernel/qwidget.h +++ b/src/widgets/kernel/qwidget.h @@ -104,6 +104,7 @@ class QGraphicsProxyWidget; class QGraphicsEffect; class QRasterWindowSurface; class QUnifiedToolbarSurface; +class QPixmap; #if defined(Q_WS_X11) class QX11Info; #endif @@ -362,6 +363,8 @@ public: const QRegion &sourceRegion = QRegion(), RenderFlags renderFlags = RenderFlags(DrawWindowBackground | DrawChildren)); + Q_INVOKABLE QPixmap grab(const QRect &rectangle); + #ifndef QT_NO_GRAPHICSEFFECT QGraphicsEffect *graphicsEffect() const; void setGraphicsEffect(QGraphicsEffect *effect); -- cgit v1.2.3