📄 qwidget.cpp
字号:
x->basew = x->baseh = 0; x->normalGeometry = QRect(0,0,-1,-1);#if defined(Q_WS_X11) x->embedded = 0; x->parentWinId = 0; x->spont_unmapped = 0; x->dnd = 0;#endif x->savedFlags = 0;#if defined(Q_WS_QWS) x->inPaintTransaction = false; x->backingStore = 0;#if !defined(QT_NO_QWS_MANAGER) x->qwsManager = 0;#endif#endif createTLSysExtra();#ifdef QWIDGET_EXTRA_DEBUG static int count = 0; qDebug() << "tlextra" << ++count;#endif }}/*! \internal Creates the widget extra data.*/void QWidgetPrivate::createExtra(){ if (!extra) { // if not exists extra = new QWExtra; extra->minw = extra->minh = 0; extra->maxw = extra->maxh = QWIDGETSIZE_MAX; extra->explicitMinSize = 0; extra->autoFillBackground = 0;#ifndef QT_NO_CURSOR extra->curs = 0;#endif extra->style = 0; extra->topextra = 0; createSysExtra();#ifdef QWIDGET_EXTRA_DEBUG static int count = 0; qDebug() << "extra" << ++count;#endif }}/*! \internal Deletes the widget extra data.*/void QWidgetPrivate::deleteExtra(){ if (extra) { // if exists#ifndef QT_NO_CURSOR delete extra->curs;#endif deleteSysExtra();#ifndef QT_NO_STYLE_STYLESHEET // dereference the stylesheet style if (QStyleSheetStyle *proxy = qobject_cast<QStyleSheetStyle *>(extra->style)) proxy->deref();#endif if (extra->topextra) { deleteTLSysExtra(); delete extra->topextra->icon; delete extra->topextra->iconPixmap;#if defined(Q_WS_QWS) && !defined(QT_NO_QWS_MANAGER) delete extra->topextra->qwsManager;#endif delete extra->topextra->windowSurface; delete extra->topextra; } delete extra; // extra->xic destroyed in QWidget::destroy() extra = 0; }}/* Returns true if the background is inherited; otherwise returns false. Mainly used in the paintOnScreen case.*/bool QWidgetPrivate::isBackgroundInherited() const{ Q_Q(const QWidget); // windows do not inherit their background if (q->isWindow() || q->windowType() == Qt::SubWindow) return false; if (q->testAttribute(Qt::WA_NoSystemBackground) || q->testAttribute(Qt::WA_OpaquePaintEvent)) return false; const QPalette &pal = q->palette(); QPalette::ColorRole bg = q->backgroundRole(); QBrush brush = pal.brush(bg); // non opaque brushes leaves us no choice, we must inherit if (!q->autoFillBackground() || !brush.isOpaque()) return true; if (brush.style() == Qt::SolidPattern) { // the background is just a solid color. If there is no // propagated contents, then we claim as performance // optimization that it was not inheritet. This is the normal // case in standard Windows or Motif style. const QWidget *w = q->parentWidget(); if (!w->d_func()->isBackgroundInherited()) return false; } return true;}#ifndef Q_WS_MAC/* Returns true if there are widgets above this which overlap with \a rect, which is in parent's coordinate system (same as crect).*/bool QWidgetPrivate::isOverlapped(const QRect &rect) const{ Q_Q(const QWidget); const QWidget *w = q; QRect r = rect; while (w) { if (w->isWindow()) return false; QWidgetPrivate *pd = w->parentWidget()->d_func(); bool above = false; for (int i = 0; i < pd->children.size(); ++i) { QWidget *sibling = qobject_cast<QWidget *>(pd->children.at(i)); if (!sibling || !sibling->isVisible() || sibling->isWindow()) continue; if (!above) { above = (sibling == w); continue; } if (sibling->data->crect.intersects(r)) return true; } w = w->parentWidget(); r.translate(pd->data.crect.topLeft()); } return false;}#endifvoid QWidgetPrivate::setUpdatesEnabled_helper(bool enable){ Q_Q(QWidget); if (enable && !q->isWindow() && q->parentWidget() && !q->parentWidget()->updatesEnabled()) return; // nothing we can do if (enable != q->testAttribute(Qt::WA_UpdatesDisabled)) return; // nothing to do q->setAttribute(Qt::WA_UpdatesDisabled, !enable); if (enable) q->update(); Qt::WidgetAttribute attribute = enable ? Qt::WA_ForceUpdatesDisabled : Qt::WA_UpdatesDisabled; for (int i = 0; i < children.size(); ++i) { QWidget *w = qobject_cast<QWidget *>(children.at(i)); if (w && !w->isWindow() && !w->testAttribute(attribute)) w->d_func()->setUpdatesEnabled_helper(enable); }}void QWidgetPrivate::propagatePaletteChange(){ Q_Q(QWidget); QEvent pc(QEvent::PaletteChange); QApplication::sendEvent(q, &pc); for (int i = 0; i < children.size(); ++i) { QWidget *w = qobject_cast<QWidget*>(children.at(i)); if (w && !w->testAttribute(Qt::WA_StyleSheet) && (!w->isWindow() || w->testAttribute(Qt::WA_WindowPropagation))) w->d_func()->resolvePalette(); }#if defined(QT3_SUPPORT) q->paletteChange(q->palette()); // compatibility#endif}/* Returns the widget's clipping rectangle.*/QRect QWidgetPrivate::clipRect() const{ Q_Q(const QWidget); const QWidget * w = q; if (!w->isVisible()) return QRect(); QRect r = q->rect(); int ox = 0; int oy = 0; while (w && w->isVisible() && !w->isWindow() && w->parentWidget()) { ox -= w->x(); oy -= w->y(); w = w->parentWidget(); r &= QRect(ox, oy, w->width(), w->height()); } return r;}/* Returns the widget's clipping region (without siblings).*/QRegion QWidgetPrivate::clipRegion() const{ Q_Q(const QWidget); if (!q->isVisible()) return QRegion(); QRegion r(q->rect()); const QWidget * w = q; const QWidget *ignoreUpTo; int ox = 0; int oy = 0; while (w && w->isVisible() && !w->isWindow() && w->parentWidget()) { ox -= w->x(); oy -= w->y(); ignoreUpTo = w; w = w->parentWidget(); r &= QRegion(ox, oy, w->width(), w->height()); int i = 0; while(w->d_func()->children.at(i++) != static_cast<const QObject *>(ignoreUpTo)) ; for ( ; i < w->d_func()->children.size(); ++i) { if(QWidget *sibling = qobject_cast<QWidget *>(w->d_func()->children.at(i))) { if(sibling->isVisible() && !sibling->isWindow()) { QRect siblingRect(ox+sibling->x(), oy+sibling->y(), sibling->width(), sibling->height()); if(siblingRect.intersects(q->rect())) r -= QRegion(siblingRect); } } } } return r;}#ifdef Q_WIDGET_CACHE_OPAQUEREGIONSvoid QWidgetPrivate::setDirtyOpaqueRegion(){ Q_Q(QWidget); dirtyOpaqueChildren = true; if (q->isWindow()) return; QWidget *parent = q->parentWidget(); if (!parent) return; // TODO: instead of setting dirtyflag, manipulate the dirtyregion directly? QWidgetPrivate *pd = parent->d_func(); if (!pd->dirtyOpaqueChildren) pd->setDirtyOpaqueRegion();}QRegion QWidgetPrivate::getOpaqueRegion() const{ Q_Q(const QWidget); QRegion r = isOpaque() ? q->rect() : getOpaqueChildren(); if (extra && !extra->mask.isEmpty()) r &= extra->mask; if (r.isEmpty()) return r; return r & clipRect();}QRegion QWidgetPrivate::getOpaqueChildren() const{ if (!dirtyOpaqueChildren) return opaqueChildren; QWidgetPrivate *that = const_cast<QWidgetPrivate*>(this); that->opaqueChildren = QRegion(); for (int i = 0; i < children.size(); ++i) { QWidget *child = qobject_cast<QWidget *>(children.at(i)); if (!child || !child->isVisible() || child->isWindow()) continue; const QPoint offset = child->geometry().topLeft(); that->opaqueChildren += child->d_func()->getOpaqueRegion().translated(offset); } that->dirtyOpaqueChildren = false; return that->opaqueChildren;}// hw: currently disable opaque children cache.// Doesn't play nice with subtractOpaqueSiblingsvoid QWidgetPrivate::subtractOpaqueChildren(QRegion &rgn, const QRegion &clipRgn, const QPoint &offset, int startIdx) const{ Q_UNUSED(startIdx); if (clipRgn.isEmpty()) return; const QRegion r = getOpaqueChildren(); if (!r.isEmpty()) rgn -= (r.translated(offset) & clipRgn);}#if defined(Q_WIDGET_USE_DIRTYLIST) || (QT_VERSION >= 0x040400)QRegion QWidgetPrivate::getOpaqueSiblings() const{ Q_Q(const QWidget); if (q->isWindow()) // no siblings return QRegion(); const QPoint myOffset = -q->data->crect.topLeft(); const QWidgetPrivate *pd = q->parentWidget()->d_func(); QRegion opaqueSiblings = pd->getOpaqueSiblings(); const int startIdx = pd->children.indexOf(const_cast<QWidget*>(q)) + 1; for (int i = startIdx; i < pd->children.size(); ++i) { const QWidget *sibling = qobject_cast<QWidget *>(pd->children.at(i)); if (!sibling || !sibling->isVisible() || sibling->isWindow()) continue; const QPoint offset = sibling->geometry().topLeft(); const QWidgetPrivate *sd = sibling->d_func(); opaqueSiblings += sd->getOpaqueRegion().translated(offset); } return opaqueSiblings.translated(myOffset);}#endif//subtract any relatives that are higher up than me --- this is too expensive !!!void QWidgetPrivate::subtractOpaqueSiblings(QRegion &rgn, const QPoint &offset) const{ static int disableSubtractOpaqueSiblings = qgetenv("QT_NO_SUBTRACTOPAQUESIBLINGS").toInt(); if (disableSubtractOpaqueSiblings) return;#if defined(Q_WIDGET_USE_DIRTYLIST) || (QT_VERSION >= 0x040400) rgn -= getOpaqueSiblings().translated(offset);#else Q_Q(const QWidget); if (q->isWindow()) return; QPoint myOffset = offset - q->data->crect.topLeft(); const QWidgetPrivate *pd = q->parentWidget()->d_func(); pd->subtractOpaqueSiblings(rgn, myOffset); const int startIdx = pd->children.indexOf(const_cast<QWidget*>(q)) + 1; for (int i = startIdx; i < pd->children.size(); ++i) { const QWidget *sibling = qobject_cast<QWidget *>(pd->children.at(i)); if (!sibling || !sibling->isVisible() || sibling->isWindow()) continue; QRegion childRgn = sibling->geometry().translated(myOffset) & q->rect(); const QWidgetPrivate *sd = sibling->d_func(); sd->subtractOpaqueChildren(rgn, childRgn, myOffset + sibling->geometry().topLeft()); }#endif}#else // Q_WIDGET_CACHE_OPAQUEREGIONSvoid QWidgetPrivate::subtractOpaqueChildren(QRegion &rgn, const QRegion &clipRgn, const QPoint &offset, int startIdx) const{ for (int i=startIdx; i < children.size(); ++i) { if (QWidget *child = qobject_cast<QWidget *>(children.at(i))) { if (child->isVisible() && !child->isWindow()) { QRegion childRgn = clipRgn & child->geometry().translated(offset); QWidgetPrivate *cd = child->d_func(); if (cd->extra && !cd->extra->mask.isEmpty()) childRgn &= cd->extra->mask.translated(offset + cd->data.crect.topLeft()); if (childRgn.isEmpty()) continue; if (cd->isOpaque()) rgn -= childRgn; else cd->subtractOpaqueChildren(rgn, childRgn, offset + child->geometry().topLeft()); } } }}//subtract any relatives that are higher up than me --- is this too expensive ???
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -