198QGraphicsWidget::~QGraphicsWidget()
200 Q_D(QGraphicsWidget);
203 for (
auto action : std::as_const(d->actions)) {
204 QActionPrivate *apriv = action->d_func();
205 apriv->associatedObjects.removeAll(
this);
210 if (QGraphicsScene *scn = scene()) {
211 QGraphicsScenePrivate *sceneD = scn->d_func();
212 if (sceneD->tabFocusFirst ==
this)
213 sceneD->tabFocusFirst = (d->focusNext ==
this ?
nullptr : d->focusNext);
215 d->focusPrev->d_func()->focusNext = d->focusNext;
216 d->focusNext->d_func()->focusPrev = d->focusPrev;
226 QGraphicsLayout *temp = d->layout;
227 const auto items = childItems();
228 for (QGraphicsItem *item : items) {
232 if (item->isWidget()) {
233 QGraphicsWidget *widget =
static_cast<QGraphicsWidget *>(item);
234 if (widget->parentLayoutItem() == d->layout)
235 widget->setParentLayoutItem(
nullptr);
243 widgetStyles()->setStyleForWidget(
this,
nullptr);
248 setParentItem(
nullptr);
320void QGraphicsWidget::setGeometry(
const QRectF &rect)
322 QGraphicsWidgetPrivate *wd = QGraphicsWidget::d_func();
325 const auto relayoutChildren = qScopeGuard([
this, wd]() {
326 if (QGraphicsLayout::instantInvalidatePropagation()) {
327 if (QGraphicsLayout *lay = wd->layout) {
328 if (!lay->isActivated()) {
329 QEvent layoutRequest(QEvent::LayoutRequest);
330 QCoreApplication::sendEvent(
this, &layoutRequest);
336 QGraphicsLayoutItemPrivate *d = QGraphicsLayoutItem::d_ptr.data();
338 QPointF oldPos = d->geom.topLeft();
340 setAttribute(Qt::WA_Resized);
342 newGeom.setSize(rect.size().expandedTo(effectiveSizeHint(Qt::MinimumSize))
343 .boundedTo(effectiveSizeHint(Qt::MaximumSize)));
345 if (newGeom == d->geom)
349 wd->inSetGeometry = 1;
350 setPos(newGeom.topLeft());
351 wd->inSetGeometry = 0;
352 newGeom.moveTopLeft(pos());
354 if (newGeom == d->geom)
359 if (wd->scene && rect.topLeft() == d->geom.topLeft())
360 prepareGeometryChange();
364 if (oldPos != pos()) {
366 QGraphicsSceneMoveEvent event;
367 event.setOldPos(oldPos);
368 event.setNewPos(pos());
369 QCoreApplication::sendEvent(
this, &event);
372 d->geom.moveTopLeft(pos());
373 emit geometryChanged();
378 QSizeF oldSize = size();
379 QGraphicsLayoutItem::setGeometry(newGeom);
381 if (newGeom.size() != oldSize) {
382 if (oldSize.width() != newGeom.size().width())
384 if (oldSize.height() != newGeom.size().height())
385 emit heightChanged();
386 QGraphicsLayout *lay = wd->layout;
387 if (!QGraphicsLayout::instantInvalidatePropagation() || !lay || lay->isActivated()) {
388 QGraphicsSceneResizeEvent re;
389 re.setOldSize(oldSize);
390 re.setNewSize(newGeom.size());
391 QCoreApplication::sendEvent(
this, &re);
395 emit geometryChanged();
572void QGraphicsWidget::unsetWindowFrameMargins()
574 Q_D(QGraphicsWidget);
575 if ((d->windowFlags & Qt::Window) && (d->windowFlags & Qt::WindowType_Mask) != Qt::Popup &&
576 (d->windowFlags & Qt::WindowType_Mask) != Qt::ToolTip && !(d->windowFlags & Qt::FramelessWindowHint)) {
577 QStyleOptionTitleBar bar;
578 d->initStyleOptionTitleBar(&bar);
579 QStyle *style =
this->style();
580 const qreal margin = style->pixelMetric(QStyle::PM_MdiSubWindowFrameWidth, &bar);
581 qreal titleBarHeight = d->titleBarHeight(bar);
582 setWindowFrameMargins(margin, titleBarHeight, margin, margin);
584 setWindowFrameMargins(0, 0, 0, 0);
586 d->setWindowFrameMargins =
false;
660void QGraphicsWidget::initStyleOption(QStyleOption *option)
const
664 option->state = QStyle::State_None;
666 option->state |= QStyle::State_Enabled;
668 option->state |= QStyle::State_HasFocus;
672 option->state |= QStyle::State_MouseOver;
673 if (QGraphicsWidget *w = window()) {
674 if (w->isActiveWindow())
675 option->state |= QStyle::State_Active;
678 option->state |= QStyle::State_Window;
680
681
682
683
684
685
686 option->direction = layoutDirection();
687 option->rect = rect().toRect();
688 option->palette = palette();
690 option->palette.setCurrentColorGroup(QPalette::Disabled);
691 }
else if (isActiveWindow()) {
692 option->palette.setCurrentColorGroup(QPalette::Active);
694 option->palette.setCurrentColorGroup(QPalette::Inactive);
696 option->fontMetrics = QFontMetrics(font());
697 option->styleObject =
const_cast<QGraphicsWidget *>(
this);
1033void QGraphicsWidget::updateGeometry()
1035 QGraphicsLayoutItem::updateGeometry();
1036 QGraphicsLayoutItem *parentItem = parentLayoutItem();
1038 if (parentItem && parentItem->isLayout()) {
1039 if (QGraphicsLayout::instantInvalidatePropagation()) {
1040 static_cast<QGraphicsLayout *>(parentItem)->invalidate();
1042 parentItem->updateGeometry();
1047 QGraphicsWidget *parentWid = parentWidget();
1048 if (parentWid->isVisible())
1049 QCoreApplication::postEvent(parentWid,
new QEvent(QEvent::LayoutRequest));
1052
1053
1054
1055
1056 if (QGraphicsLayout::instantInvalidatePropagation())
1057 QCoreApplication::postEvent(
static_cast<QGraphicsWidget *>(
this),
new QEvent(QEvent::LayoutRequest));
1059 if (!QGraphicsLayout::instantInvalidatePropagation()) {
1060 bool wasResized = testAttribute(Qt::WA_Resized);
1062 setAttribute(Qt::WA_Resized, wasResized);
1087QVariant QGraphicsWidget::itemChange(GraphicsItemChange change,
const QVariant &value)
1089 Q_D(QGraphicsWidget);
1091 case ItemEnabledHasChanged: {
1093 QEvent event(QEvent::EnabledChange);
1094 QCoreApplication::sendEvent(
this, &event);
1097 case ItemVisibleChange:
1098 if (value.toBool()) {
1101 QCoreApplication::sendEvent(
this, &event);
1102 bool resized = testAttribute(Qt::WA_Resized);
1105 setAttribute(Qt::WA_Resized,
false);
1110 if (value.toBool() || d->explicitlyHidden)
1113 case ItemVisibleHasChanged:
1114 if (!value.toBool()) {
1117 QCoreApplication::sendEvent(
this, &event);
1120 case ItemPositionHasChanged:
1121 d->setGeometryFromSetPos();
1123 case ItemParentChange: {
1125 QEvent event(QEvent::ParentAboutToChange);
1126 QCoreApplication::sendEvent(
this, &event);
1129 case ItemParentHasChanged: {
1131 QEvent event(QEvent::ParentChange);
1132 QCoreApplication::sendEvent(
this, &event);
1135 case ItemCursorHasChanged: {
1137 QEvent event(QEvent::CursorChange);
1138 QCoreApplication::sendEvent(
this, &event);
1141 case ItemToolTipHasChanged: {
1143 QEvent event(QEvent::ToolTipChange);
1144 QCoreApplication::sendEvent(
this, &event);
1150 return QGraphicsItem::itemChange(change, value);
1214bool QGraphicsWidget::windowFrameEvent(QEvent *event)
1216 Q_D(QGraphicsWidget);
1217 switch (event->type()) {
1218 case QEvent::GraphicsSceneMousePress:
1219 d->windowFrameMousePressEvent(
static_cast<QGraphicsSceneMouseEvent *>(event));
1221 case QEvent::GraphicsSceneMouseMove:
1222 d->ensureWindowData();
1223 if (d->windowData->grabbedSection != Qt::NoSection) {
1224 d->windowFrameMouseMoveEvent(
static_cast<QGraphicsSceneMouseEvent *>(event));
1228 case QEvent::GraphicsSceneMouseRelease:
1229 d->windowFrameMouseReleaseEvent(
static_cast<QGraphicsSceneMouseEvent *>(event));
1231 case QEvent::GraphicsSceneHoverMove:
1232 d->windowFrameHoverMoveEvent(
static_cast<QGraphicsSceneHoverEvent *>(event));
1234 case QEvent::GraphicsSceneHoverLeave:
1235 d->windowFrameHoverLeaveEvent(
static_cast<QGraphicsSceneHoverEvent *>(event));
1240 return event->isAccepted();
1261Qt::WindowFrameSection QGraphicsWidget::windowFrameSectionAt(
const QPointF &pos)
const
1263 Q_D(
const QGraphicsWidget);
1265 const QRectF r = windowFrameRect();
1266 if (!r.contains(pos))
1267 return Qt::NoSection;
1269 const qreal left = r.left();
1270 const qreal top = r.top();
1271 const qreal right = r.right();
1272 const qreal bottom = r.bottom();
1273 const qreal x = pos.x();
1274 const qreal y = pos.y();
1276 const qreal cornerMargin = 20;
1278 const qreal windowFrameWidth = d->windowFrameMargins
1279 ? d->windowFrameMargins->left() : 0;
1281 Qt::WindowFrameSection s = Qt::NoSection;
1282 if (x <= left + cornerMargin) {
1283 if (y <= top + windowFrameWidth || (x <= left + windowFrameWidth && y <= top + cornerMargin)) {
1284 s = Qt::TopLeftSection;
1285 }
else if (y >= bottom - windowFrameWidth || (x <= left + windowFrameWidth && y >= bottom - cornerMargin)) {
1286 s = Qt::BottomLeftSection;
1287 }
else if (x <= left + windowFrameWidth) {
1288 s = Qt::LeftSection;
1290 }
else if (x >= right - cornerMargin) {
1291 if (y <= top + windowFrameWidth || (x >= right - windowFrameWidth && y <= top + cornerMargin)) {
1292 s = Qt::TopRightSection;
1293 }
else if (y >= bottom - windowFrameWidth || (x >= right - windowFrameWidth && y >= bottom - cornerMargin)) {
1294 s = Qt::BottomRightSection;
1295 }
else if (x >= right - windowFrameWidth) {
1296 s = Qt::RightSection;
1298 }
else if (y <= top + windowFrameWidth) {
1300 }
else if (y >= bottom - windowFrameWidth) {
1301 s = Qt::BottomSection;
1303 if (s == Qt::NoSection) {
1305 r1.setHeight(d->windowFrameMargins
1306 ? d->windowFrameMargins->top() : 0);
1307 if (r1.contains(pos))
1308 s = Qt::TitleBarArea;
1350bool QGraphicsWidget::event(QEvent *event)
1352 Q_D(QGraphicsWidget);
1355 d->layout->widgetEvent(event);
1358 switch (event->type()) {
1359 case QEvent::GraphicsSceneMove:
1360 moveEvent(
static_cast<QGraphicsSceneMoveEvent *>(event));
1362 case QEvent::GraphicsSceneResize:
1363 resizeEvent(
static_cast<QGraphicsSceneResizeEvent *>(event));
1366 showEvent(
static_cast<QShowEvent *>(event));
1369 hideEvent(
static_cast<QHideEvent *>(event));
1371 case QEvent::Polish:
1374 if (!d->font.isCopyOf(QApplication::font()))
1375 d->updateFont(d->font);
1377 case QEvent::WindowActivate:
1378 case QEvent::WindowDeactivate:
1381 case QEvent::StyleAnimationUpdate:
1388 case QEvent::ActivationChange:
1389 case QEvent::EnabledChange:
1390 case QEvent::FontChange:
1391 case QEvent::StyleChange:
1392 case QEvent::PaletteChange:
1393 case QEvent::ParentChange:
1394 case QEvent::ContentsRectChange:
1395 case QEvent::LayoutDirectionChange:
1399 closeEvent((QCloseEvent *)event);
1401 case QEvent::GrabMouse:
1402 grabMouseEvent(event);
1404 case QEvent::UngrabMouse:
1405 ungrabMouseEvent(event);
1407 case QEvent::GrabKeyboard:
1408 grabKeyboardEvent(event);
1410 case QEvent::UngrabKeyboard:
1411 ungrabKeyboardEvent(event);
1413 case QEvent::GraphicsSceneMousePress:
1414 if (d->hasDecoration() && windowFrameEvent(event))
1417 case QEvent::GraphicsSceneMouseMove:
1418 case QEvent::GraphicsSceneMouseRelease:
1419 case QEvent::GraphicsSceneMouseDoubleClick:
1420 d->ensureWindowData();
1421 if (d->hasDecoration() && d->windowData->grabbedSection != Qt::NoSection)
1422 return windowFrameEvent(event);
1424 case QEvent::GraphicsSceneHoverEnter:
1425 case QEvent::GraphicsSceneHoverMove:
1426 case QEvent::GraphicsSceneHoverLeave:
1427 if (d->hasDecoration()) {
1428 windowFrameEvent(event);
1431 if (!acceptHoverEvents())
1438 return QObject::event(event);
1729void QGraphicsWidget::setWindowFlags(Qt::WindowFlags wFlags)
1731 Q_D(QGraphicsWidget);
1732 if (d->windowFlags == wFlags)
1734 bool wasPopup = (d->windowFlags & Qt::WindowType_Mask) == Qt::Popup;
1736 d->adjustWindowFlags(&wFlags);
1737 d->windowFlags = wFlags;
1738 if (!d->setWindowFrameMargins)
1739 unsetWindowFrameMargins();
1741 setFlag(ItemIsPanel, d->windowFlags & Qt::Window);
1743 bool isPopup = (d->windowFlags & Qt::WindowType_Mask) == Qt::Popup;
1744 if (d->scene && isVisible() && wasPopup != isPopup) {
1747 d->scene->d_func()->removePopup(
this);
1749 d->scene->d_func()->addPopup(
this);
1752 if (d->scene && d->scene->d_func()->allItemsIgnoreHoverEvents && d->hasDecoration()) {
1753 d->scene->d_func()->allItemsIgnoreHoverEvents =
false;
1754 d->scene->d_func()->enableMouseTrackingOnViews();
1988void QGraphicsWidget::insertAction(QAction *before, QAction *action)
1991 qWarning(
"QWidget::insertAction: Attempt to insert null action");
1995 Q_D(QGraphicsWidget);
1996 int index = d->actions.indexOf(action);
1998 d->actions.removeAt(index);
2000 int pos = d->actions.indexOf(before);
2003 pos = d->actions.size();
2005 d->actions.insert(pos, action);
2008 QActionPrivate *apriv = action->d_func();
2009 apriv->associatedObjects.append(
this);
2012 QActionEvent e(QEvent::ActionAdded, action, before);
2013 QCoreApplication::sendEvent(
this, &e);
2095void QGraphicsWidget::setTabOrder(QGraphicsWidget *first, QGraphicsWidget *second)
2097 if (!first && !second) {
2098 qWarning(
"QGraphicsWidget::setTabOrder(0, 0) is undefined");
2101 if ((first && second) && first->scene() != second->scene()) {
2102 qWarning(
"QGraphicsWidget::setTabOrder: scenes %p and %p are different",
2103 first->scene(), second->scene());
2106 QGraphicsScene *scene = first ? first->scene() : second->scene();
2108 qWarning(
"QGraphicsWidget::setTabOrder: assigning tab order from/to the"
2109 " scene requires the item to be in a scene.");
2116 QGraphicsScenePrivate *sceneD = scene->d_func();
2118 sceneD->tabFocusFirst = second;
2122 sceneD->tabFocusFirst = first->d_func()->focusNext;
2127 QGraphicsWidget *firstFocusNext = first->d_func()->focusNext;
2128 if (firstFocusNext == second) {
2134 QGraphicsWidget *secondFocusPrev = second->d_func()->focusPrev;
2135 QGraphicsWidget *secondFocusNext = second->d_func()->focusNext;
2136 firstFocusNext->d_func()->focusPrev = second;
2137 first->d_func()->focusNext = second;
2138 second->d_func()->focusNext = firstFocusNext;
2139 second->d_func()->focusPrev = first;
2140 secondFocusPrev->d_func()->focusNext = secondFocusNext;
2141 secondFocusNext->d_func()->focusPrev = secondFocusPrev;
2143 Q_ASSERT(first->d_func()->focusNext->d_func()->focusPrev == first);
2144 Q_ASSERT(first->d_func()->focusPrev->d_func()->focusNext == first);
2146 Q_ASSERT(second->d_func()->focusNext->d_func()->focusPrev == second);
2147 Q_ASSERT(second->d_func()->focusPrev->d_func()->focusNext == second);
2218void QGraphicsWidget::paintWindowFrame(QPainter *painter,
const QStyleOptionGraphicsItem *option,
2221 const bool fillBackground = !testAttribute(Qt::WA_OpaquePaintEvent)
2222 && !testAttribute(Qt::WA_NoSystemBackground);
2223 QGraphicsProxyWidget *proxy = qobject_cast<QGraphicsProxyWidget *>(
this);
2224 const bool embeddedWidgetFillsOwnBackground = proxy && proxy->widget();
2226 if (rect().contains(option->exposedRect)) {
2227 if (fillBackground && !embeddedWidgetFillsOwnBackground)
2228 painter->fillRect(option->exposedRect, palette().window());
2232 Q_D(QGraphicsWidget);
2234 QRect windowFrameRect = QRect(QPoint(), windowFrameGeometry().size().toSize());
2235 QStyleOptionTitleBar bar;
2236 bar.QStyleOption::operator=(*option);
2237 d->initStyleOptionTitleBar(&bar);
2238 d->ensureWindowData();
2239 bar.state.setFlag(QStyle::State_MouseOver, d->windowData->buttonMouseOver);
2240 bar.state.setFlag(QStyle::State_Sunken, d->windowData->buttonSunken);
2241 bar.rect = windowFrameRect;
2244 const QPointF styleOrigin =
this->windowFrameRect().topLeft();
2245 painter->translate(styleOrigin);
2248 const QSize pixmapSize = windowFrameRect.size();
2249 if (pixmapSize.width() <= 0 || pixmapSize.height() <= 0)
2251 QPainter *realPainter = painter;
2252 QPixmap pm(pixmapSize);
2253 painter =
new QPainter(&pm);
2257 QStyleHintReturnMask mask;
2258 bool setMask = style()->styleHint(QStyle::SH_WindowFrame_Mask, &bar, widget, &mask) && !mask.region.isEmpty();
2259 bool hasBorder = !style()->styleHint(QStyle::SH_TitleBar_NoBorder, &bar, widget);
2260 int frameWidth = style()->pixelMetric(QStyle::PM_MdiSubWindowFrameWidth, &bar, widget);
2263 painter->setClipRegion(mask.region, Qt::IntersectClip);
2265 if (fillBackground) {
2266 if (embeddedWidgetFillsOwnBackground) {
2268 QPainterPath windowFrameBackground;
2269 windowFrameBackground.addRect(windowFrameRect);
2272 windowFrameBackground.addRect(rect().translated(-styleOrigin).adjusted(0.5, 0.5, -0.5, -0.5));
2273 painter->fillPath(windowFrameBackground, palette().window());
2275 painter->fillRect(windowFrameRect, palette().window());
2280 int height = (
int)d->titleBarHeight(bar);
2281 bar.rect.setHeight(height);
2283 bar.rect.adjust(frameWidth, frameWidth, -frameWidth, 0);
2286 painter->setFont(QApplication::font(
"QMdiSubWindowTitleBar"));
2287 style()->drawComplexControl(QStyle::CC_TitleBar, &bar, painter, widget);
2292 QStyleOptionFrame frameOptions;
2293 frameOptions.QStyleOption::operator=(*option);
2294 initStyleOption(&frameOptions);
2296 painter->setClipRect(windowFrameRect.adjusted(0, +height, 0, 0), Qt::IntersectClip);
2297 frameOptions.state.setFlag(QStyle::State_HasFocus, hasFocus());
2298 bool isActive = isActiveWindow();
2299 frameOptions.state.setFlag(QStyle::State_Active, isActive);
2301 frameOptions.palette.setCurrentColorGroup(isActive ? QPalette::Active : QPalette::Normal);
2302 frameOptions.rect = windowFrameRect;
2303 frameOptions.lineWidth = style()->pixelMetric(QStyle::PM_MdiSubWindowFrameWidth,
nullptr, widget);
2304 frameOptions.midLineWidth = 1;
2305 style()->drawPrimitive(QStyle::PE_FrameWindow, &frameOptions, painter, widget);
2308 realPainter->drawPixmap(QPoint(), pm);