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;
679 option->direction = layoutDirection();
680 option->rect = rect().toRect();
681 option->palette = palette();
683 option->palette.setCurrentColorGroup(QPalette::Disabled);
684 }
else if (isActiveWindow()) {
685 option->palette.setCurrentColorGroup(QPalette::Active);
687 option->palette.setCurrentColorGroup(QPalette::Inactive);
689 option->fontMetrics = QFontMetrics(font());
690 option->styleObject =
const_cast<QGraphicsWidget *>(
this);
1026void QGraphicsWidget::updateGeometry()
1028 QGraphicsLayoutItem::updateGeometry();
1029 QGraphicsLayoutItem *parentItem = parentLayoutItem();
1031 if (parentItem && parentItem->isLayout()) {
1032 if (QGraphicsLayout::instantInvalidatePropagation()) {
1033 static_cast<QGraphicsLayout *>(parentItem)->invalidate();
1035 parentItem->updateGeometry();
1040 QGraphicsWidget *parentWid = parentWidget();
1041 if (parentWid->isVisible())
1042 QCoreApplication::postEvent(parentWid,
new QEvent(QEvent::LayoutRequest));
1045
1046
1047
1048
1049 if (QGraphicsLayout::instantInvalidatePropagation())
1050 QCoreApplication::postEvent(
static_cast<QGraphicsWidget *>(
this),
new QEvent(QEvent::LayoutRequest));
1052 if (!QGraphicsLayout::instantInvalidatePropagation()) {
1053 bool wasResized = testAttribute(Qt::WA_Resized);
1055 setAttribute(Qt::WA_Resized, wasResized);
1080QVariant QGraphicsWidget::itemChange(GraphicsItemChange change,
const QVariant &value)
1082 Q_D(QGraphicsWidget);
1084 case ItemEnabledHasChanged: {
1086 QEvent event(QEvent::EnabledChange);
1087 QCoreApplication::sendEvent(
this, &event);
1090 case ItemVisibleChange:
1091 if (value.toBool()) {
1094 QCoreApplication::sendEvent(
this, &event);
1095 bool resized = testAttribute(Qt::WA_Resized);
1098 setAttribute(Qt::WA_Resized,
false);
1103 if (value.toBool() || d->explicitlyHidden)
1106 case ItemVisibleHasChanged:
1107 if (!value.toBool()) {
1110 QCoreApplication::sendEvent(
this, &event);
1113 case ItemPositionHasChanged:
1114 d->setGeometryFromSetPos();
1116 case ItemParentChange: {
1118 QEvent event(QEvent::ParentAboutToChange);
1119 QCoreApplication::sendEvent(
this, &event);
1122 case ItemParentHasChanged: {
1124 QEvent event(QEvent::ParentChange);
1125 QCoreApplication::sendEvent(
this, &event);
1128 case ItemCursorHasChanged: {
1130 QEvent event(QEvent::CursorChange);
1131 QCoreApplication::sendEvent(
this, &event);
1134 case ItemToolTipHasChanged: {
1136 QEvent event(QEvent::ToolTipChange);
1137 QCoreApplication::sendEvent(
this, &event);
1143 return QGraphicsItem::itemChange(change, value);
1207bool QGraphicsWidget::windowFrameEvent(QEvent *event)
1209 Q_D(QGraphicsWidget);
1210 switch (event->type()) {
1211 case QEvent::GraphicsSceneMousePress:
1212 d->windowFrameMousePressEvent(
static_cast<QGraphicsSceneMouseEvent *>(event));
1214 case QEvent::GraphicsSceneMouseMove:
1215 d->ensureWindowData();
1216 if (d->windowData->grabbedSection != Qt::NoSection) {
1217 d->windowFrameMouseMoveEvent(
static_cast<QGraphicsSceneMouseEvent *>(event));
1221 case QEvent::GraphicsSceneMouseRelease:
1222 d->windowFrameMouseReleaseEvent(
static_cast<QGraphicsSceneMouseEvent *>(event));
1224 case QEvent::GraphicsSceneHoverMove:
1225 d->windowFrameHoverMoveEvent(
static_cast<QGraphicsSceneHoverEvent *>(event));
1227 case QEvent::GraphicsSceneHoverLeave:
1228 d->windowFrameHoverLeaveEvent(
static_cast<QGraphicsSceneHoverEvent *>(event));
1233 return event->isAccepted();
1254Qt::WindowFrameSection QGraphicsWidget::windowFrameSectionAt(
const QPointF &pos)
const
1256 Q_D(
const QGraphicsWidget);
1258 const QRectF r = windowFrameRect();
1259 if (!r.contains(pos))
1260 return Qt::NoSection;
1262 const qreal left = r.left();
1263 const qreal top = r.top();
1264 const qreal right = r.right();
1265 const qreal bottom = r.bottom();
1266 const qreal x = pos.x();
1267 const qreal y = pos.y();
1269 const qreal cornerMargin = 20;
1271 const qreal windowFrameWidth = d->windowFrameMargins
1272 ? d->windowFrameMargins->left() : 0;
1274 Qt::WindowFrameSection s = Qt::NoSection;
1275 if (x <= left + cornerMargin) {
1276 if (y <= top + windowFrameWidth || (x <= left + windowFrameWidth && y <= top + cornerMargin)) {
1277 s = Qt::TopLeftSection;
1278 }
else if (y >= bottom - windowFrameWidth || (x <= left + windowFrameWidth && y >= bottom - cornerMargin)) {
1279 s = Qt::BottomLeftSection;
1280 }
else if (x <= left + windowFrameWidth) {
1281 s = Qt::LeftSection;
1283 }
else if (x >= right - cornerMargin) {
1284 if (y <= top + windowFrameWidth || (x >= right - windowFrameWidth && y <= top + cornerMargin)) {
1285 s = Qt::TopRightSection;
1286 }
else if (y >= bottom - windowFrameWidth || (x >= right - windowFrameWidth && y >= bottom - cornerMargin)) {
1287 s = Qt::BottomRightSection;
1288 }
else if (x >= right - windowFrameWidth) {
1289 s = Qt::RightSection;
1291 }
else if (y <= top + windowFrameWidth) {
1293 }
else if (y >= bottom - windowFrameWidth) {
1294 s = Qt::BottomSection;
1296 if (s == Qt::NoSection) {
1298 r1.setHeight(d->windowFrameMargins
1299 ? d->windowFrameMargins->top() : 0);
1300 if (r1.contains(pos))
1301 s = Qt::TitleBarArea;
1343bool QGraphicsWidget::event(QEvent *event)
1345 Q_D(QGraphicsWidget);
1348 d->layout->widgetEvent(event);
1351 switch (event->type()) {
1352 case QEvent::GraphicsSceneMove:
1353 moveEvent(
static_cast<QGraphicsSceneMoveEvent *>(event));
1355 case QEvent::GraphicsSceneResize:
1356 resizeEvent(
static_cast<QGraphicsSceneResizeEvent *>(event));
1359 showEvent(
static_cast<QShowEvent *>(event));
1362 hideEvent(
static_cast<QHideEvent *>(event));
1364 case QEvent::Polish:
1367 if (!d->font.isCopyOf(QApplication::font()))
1368 d->updateFont(d->font);
1370 case QEvent::WindowActivate:
1371 case QEvent::WindowDeactivate:
1374 case QEvent::StyleAnimationUpdate:
1381 case QEvent::ActivationChange:
1382 case QEvent::EnabledChange:
1383 case QEvent::FontChange:
1384 case QEvent::StyleChange:
1385 case QEvent::PaletteChange:
1386 case QEvent::ParentChange:
1387 case QEvent::ContentsRectChange:
1388 case QEvent::LayoutDirectionChange:
1392 closeEvent((QCloseEvent *)event);
1394 case QEvent::GrabMouse:
1395 grabMouseEvent(event);
1397 case QEvent::UngrabMouse:
1398 ungrabMouseEvent(event);
1400 case QEvent::GrabKeyboard:
1401 grabKeyboardEvent(event);
1403 case QEvent::UngrabKeyboard:
1404 ungrabKeyboardEvent(event);
1406 case QEvent::GraphicsSceneMousePress:
1407 if (d->hasDecoration() && windowFrameEvent(event))
1410 case QEvent::GraphicsSceneMouseMove:
1411 case QEvent::GraphicsSceneMouseRelease:
1412 case QEvent::GraphicsSceneMouseDoubleClick:
1413 d->ensureWindowData();
1414 if (d->hasDecoration() && d->windowData->grabbedSection != Qt::NoSection)
1415 return windowFrameEvent(event);
1417 case QEvent::GraphicsSceneHoverEnter:
1418 case QEvent::GraphicsSceneHoverMove:
1419 case QEvent::GraphicsSceneHoverLeave:
1420 if (d->hasDecoration()) {
1421 windowFrameEvent(event);
1424 if (!acceptHoverEvents())
1431 return QObject::event(event);
1722void QGraphicsWidget::setWindowFlags(Qt::WindowFlags wFlags)
1724 Q_D(QGraphicsWidget);
1725 if (d->windowFlags == wFlags)
1727 bool wasPopup = (d->windowFlags & Qt::WindowType_Mask) == Qt::Popup;
1729 d->adjustWindowFlags(&wFlags);
1730 d->windowFlags = wFlags;
1731 if (!d->setWindowFrameMargins)
1732 unsetWindowFrameMargins();
1734 setFlag(ItemIsPanel, d->windowFlags & Qt::Window);
1736 bool isPopup = (d->windowFlags & Qt::WindowType_Mask) == Qt::Popup;
1737 if (d->scene && isVisible() && wasPopup != isPopup) {
1740 d->scene->d_func()->removePopup(
this);
1742 d->scene->d_func()->addPopup(
this);
1745 if (d->scene && d->scene->d_func()->allItemsIgnoreHoverEvents && d->hasDecoration()) {
1746 d->scene->d_func()->allItemsIgnoreHoverEvents =
false;
1747 d->scene->d_func()->enableMouseTrackingOnViews();
1981void QGraphicsWidget::insertAction(QAction *before, QAction *action)
1984 qWarning(
"QWidget::insertAction: Attempt to insert null action");
1988 Q_D(QGraphicsWidget);
1989 int index = d->actions.indexOf(action);
1991 d->actions.removeAt(index);
1993 int pos = d->actions.indexOf(before);
1996 pos = d->actions.size();
1998 d->actions.insert(pos, action);
2001 QActionPrivate *apriv = action->d_func();
2002 apriv->associatedObjects.append(
this);
2005 QActionEvent e(QEvent::ActionAdded, action, before);
2006 QCoreApplication::sendEvent(
this, &e);
2088void QGraphicsWidget::setTabOrder(QGraphicsWidget *first, QGraphicsWidget *second)
2090 if (!first && !second) {
2091 qWarning(
"QGraphicsWidget::setTabOrder(0, 0) is undefined");
2094 if ((first && second) && first->scene() != second->scene()) {
2095 qWarning(
"QGraphicsWidget::setTabOrder: scenes %p and %p are different",
2096 first->scene(), second->scene());
2099 QGraphicsScene *scene = first ? first->scene() : second->scene();
2101 qWarning(
"QGraphicsWidget::setTabOrder: assigning tab order from/to the"
2102 " scene requires the item to be in a scene.");
2109 QGraphicsScenePrivate *sceneD = scene->d_func();
2111 sceneD->tabFocusFirst = second;
2115 sceneD->tabFocusFirst = first->d_func()->focusNext;
2120 QGraphicsWidget *firstFocusNext = first->d_func()->focusNext;
2121 if (firstFocusNext == second) {
2127 QGraphicsWidget *secondFocusPrev = second->d_func()->focusPrev;
2128 QGraphicsWidget *secondFocusNext = second->d_func()->focusNext;
2129 firstFocusNext->d_func()->focusPrev = second;
2130 first->d_func()->focusNext = second;
2131 second->d_func()->focusNext = firstFocusNext;
2132 second->d_func()->focusPrev = first;
2133 secondFocusPrev->d_func()->focusNext = secondFocusNext;
2134 secondFocusNext->d_func()->focusPrev = secondFocusPrev;
2136 Q_ASSERT(first->d_func()->focusNext->d_func()->focusPrev == first);
2137 Q_ASSERT(first->d_func()->focusPrev->d_func()->focusNext == first);
2139 Q_ASSERT(second->d_func()->focusNext->d_func()->focusPrev == second);
2140 Q_ASSERT(second->d_func()->focusPrev->d_func()->focusNext == second);
2211void QGraphicsWidget::paintWindowFrame(QPainter *painter,
const QStyleOptionGraphicsItem *option,
2214 const bool fillBackground = !testAttribute(Qt::WA_OpaquePaintEvent)
2215 && !testAttribute(Qt::WA_NoSystemBackground);
2216 QGraphicsProxyWidget *proxy = qobject_cast<QGraphicsProxyWidget *>(
this);
2217 const bool embeddedWidgetFillsOwnBackground = proxy && proxy->widget();
2219 if (rect().contains(option->exposedRect)) {
2220 if (fillBackground && !embeddedWidgetFillsOwnBackground)
2221 painter->fillRect(option->exposedRect, palette().window());
2225 Q_D(QGraphicsWidget);
2227 QRect windowFrameRect = QRect(QPoint(), windowFrameGeometry().size().toSize());
2228 QStyleOptionTitleBar bar;
2229 bar.QStyleOption::operator=(*option);
2230 d->initStyleOptionTitleBar(&bar);
2231 d->ensureWindowData();
2232 bar.state.setFlag(QStyle::State_MouseOver, d->windowData->buttonMouseOver);
2233 bar.state.setFlag(QStyle::State_Sunken, d->windowData->buttonSunken);
2234 bar.rect = windowFrameRect;
2237 const QPointF styleOrigin =
this->windowFrameRect().topLeft();
2238 painter->translate(styleOrigin);
2241 const QSize pixmapSize = windowFrameRect.size();
2242 if (pixmapSize.width() <= 0 || pixmapSize.height() <= 0)
2244 QPainter *realPainter = painter;
2245 QPixmap pm(pixmapSize);
2246 painter =
new QPainter(&pm);
2250 QStyleHintReturnMask mask;
2251 bool setMask = style()->styleHint(QStyle::SH_WindowFrame_Mask, &bar, widget, &mask) && !mask.region.isEmpty();
2252 bool hasBorder = !style()->styleHint(QStyle::SH_TitleBar_NoBorder, &bar, widget);
2253 int frameWidth = style()->pixelMetric(QStyle::PM_MdiSubWindowFrameWidth, &bar, widget);
2256 painter->setClipRegion(mask.region, Qt::IntersectClip);
2258 if (fillBackground) {
2259 if (embeddedWidgetFillsOwnBackground) {
2261 QPainterPath windowFrameBackground;
2262 windowFrameBackground.addRect(windowFrameRect);
2265 windowFrameBackground.addRect(rect().translated(-styleOrigin).adjusted(0.5, 0.5, -0.5, -0.5));
2266 painter->fillPath(windowFrameBackground, palette().window());
2268 painter->fillRect(windowFrameRect, palette().window());
2273 int height = (
int)d->titleBarHeight(bar);
2274 bar.rect.setHeight(height);
2276 bar.rect.adjust(frameWidth, frameWidth, -frameWidth, 0);
2279 painter->setFont(QApplication::font(
"QMdiSubWindowTitleBar"));
2280 style()->drawComplexControl(QStyle::CC_TitleBar, &bar, painter, widget);
2285 QStyleOptionFrame frameOptions;
2286 frameOptions.QStyleOption::operator=(*option);
2287 initStyleOption(&frameOptions);
2289 painter->setClipRect(windowFrameRect.adjusted(0, +height, 0, 0), Qt::IntersectClip);
2290 frameOptions.state.setFlag(QStyle::State_HasFocus, hasFocus());
2291 bool isActive = isActiveWindow();
2292 frameOptions.state.setFlag(QStyle::State_Active, isActive);
2294 frameOptions.palette.setCurrentColorGroup(isActive ? QPalette::Active : QPalette::Normal);
2295 frameOptions.rect = windowFrameRect;
2296 frameOptions.lineWidth = style()->pixelMetric(QStyle::PM_MdiSubWindowFrameWidth,
nullptr, widget);
2297 frameOptions.midLineWidth = 1;
2298 style()->drawPrimitive(QStyle::PE_FrameWindow, &frameOptions, painter, widget);
2301 realPainter->drawPixmap(QPoint(), pm);