1 /****************************************************************************
3 ** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
4 ** All rights reserved.
5 ** Contact: Nokia Corporation (qt-info@nokia.com)
7 ** This file is part of the QtGui module of the Qt Toolkit.
9 ** $QT_BEGIN_LICENSE:LGPL$
10 ** No Commercial Usage
11 ** This file contains pre-release code and may not be distributed.
12 ** You may use this file in accordance with the terms and conditions
13 ** contained in the Technology Preview License Agreement accompanying
16 ** GNU Lesser General Public License Usage
17 ** Alternatively, this file may be used under the terms of the GNU Lesser
18 ** General Public License version 2.1 as published by the Free Software
19 ** Foundation and appearing in the file LICENSE.LGPL included in the
20 ** packaging of this file. Please review the following information to
21 ** ensure the GNU Lesser General Public License version 2.1 requirements
22 ** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
24 ** In addition, as a special exception, Nokia gives you certain additional
25 ** rights. These rights are described in the Nokia Qt LGPL Exception
26 ** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
28 ** If you have questions regarding the use of this file, please contact
29 ** Nokia at qt-info@nokia.com.
40 ****************************************************************************/
44 #ifndef QT_NO_GRAPHICSVIEW
46 #include "qgraphicswidget.h"
47 #include "qgraphicswidget_p.h"
48 #include "qgraphicslayout.h"
49 #include "qgraphicslayout_p.h"
50 #include "qgraphicsscene.h"
51 #include "qgraphicssceneevent.h"
54 #include <private/qaction_p.h>
56 #include <private/qapplication_p.h>
57 #include <private/qgraphicsscene_p.h>
58 #ifndef QT_NO_SHORTCUT
59 #include <private/qshortcutmap_p.h>
61 #include <QtCore/qmutex.h>
62 #include <QtWidgets/qapplication.h>
63 #include <QtWidgets/qgraphicsview.h>
64 #include <QtWidgets/qgraphicsproxywidget.h>
65 #include <QtGui/qpalette.h>
66 #include <QtWidgets/qstyleoption.h>
73 \class QGraphicsWidget
74 \brief The QGraphicsWidget class is the base class for all widget
75 items in a QGraphicsScene.
77 \ingroup graphicsview-api
79 QGraphicsWidget is an extended base item that provides extra functionality
80 over QGraphicsItem. It is similar to QWidget in many ways:
83 \o Provides a \l palette, a \l font and a \l style().
84 \o Has a defined geometry().
85 \o Supports layouts with setLayout() and layout().
86 \o Supports shortcuts and actions with grabShortcut() and insertAction()
89 Unlike QGraphicsItem, QGraphicsWidget is not an abstract class; you can
90 create instances of a QGraphicsWidget without having to subclass it.
91 This approach is useful for widgets that only serve the purpose of
92 organizing child widgets into a layout.
94 QGraphicsWidget can be used as a base item for your own custom item if
95 you require advanced input focus handling, e.g., tab focus and activation, or
98 Since QGraphicsWidget resembles QWidget and has similar API, it is
99 easier to port a widget from QWidget to QGraphicsWidget, instead of
102 \note QWidget-based widgets can be directly embedded into a
103 QGraphicsScene using QGraphicsProxyWidget.
105 Noticeable differences between QGraphicsWidget and QWidget are:
108 \header \o QGraphicsWidget
110 \row \o Coordinates and geometry are defined with qreals (doubles or
111 floats, depending on the platform).
112 \o QWidget uses integer geometry (QPoint, QRect).
113 \row \o The widget is already visible by default; you do not have to
114 call show() to display the widget.
115 \o QWidget is hidden by default until you call show().
116 \row \o A subset of widget attributes are supported.
117 \o All widget attributes are supported.
118 \row \o A top-level item's style defaults to QGraphicsScene::style
119 \o A top-level widget's style defaults to QApplication::style
120 \row \o Graphics View provides a custom drag and drop framework, different
122 \o Standard drag and drop framework.
123 \row \o Widget items do not support modality.
124 \o Full modality support.
127 QGraphicsWidget supports a subset of Qt's widget attributes,
128 (Qt::WidgetAttribute), as shown in the table below. Any attributes not
129 listed in this table are unsupported, or otherwise unused.
132 \header \o Widget Attribute \o Usage
133 \row \o Qt::WA_SetLayoutDirection
134 \o Set by setLayoutDirection(), cleared by
135 unsetLayoutDirection(). You can test this attribute to
136 check if the widget has been explicitly assigned a
137 \l{QGraphicsWidget::layoutDirection()}
138 {layoutDirection}. If the attribute is not set, the
139 \l{QGraphicsWidget::layoutDirection()}
140 {layoutDirection()} is inherited.
141 \row \o Qt::WA_RightToLeft
142 \o Toggled by setLayoutDirection(). Inherited from the
143 parent/scene. If set, the widget's layout will order
144 horizontally arranged widgets from right to left.
145 \row \o Qt::WA_SetStyle
146 \o Set and cleared by setStyle(). If this attribute is
147 set, the widget has been explicitly assigned a style.
148 If it is unset, the widget will use the scene's or the
150 \row \o Qt::WA_Resized
151 \o Set by setGeometry() and resize().
152 \row \o Qt::WA_SetPalette
153 \o Set by setPalette().
154 \row \o Qt::WA_SetFont
155 \o Set by setPalette().
156 \row \o Qt::WA_WindowPropagation
157 \o Enables propagation to window widgets.
160 Although QGraphicsWidget inherits from both QObject and QGraphicsItem,
161 you should use the functions provided by QGraphicsItem, \e not QObject, to
162 manage the relationships between parent and child items. These functions
163 control the stacking order of items as well as their ownership.
165 \note The QObject::parent() should always return 0 for QGraphicsWidgets,
166 but this policy is not strictly defined.
168 \sa QGraphicsProxyWidget, QGraphicsItem, {Widgets and Layouts}
172 Constructs a QGraphicsWidget instance. The optional \a parent argument is
173 passed to QGraphicsItem's constructor. The optional \a wFlags argument
174 specifies the widget's window flags (e.g., whether the widget should be a
175 window, a tool, a popup, etc).
177 QGraphicsWidget::QGraphicsWidget(QGraphicsItem *parent, Qt::WindowFlags wFlags)
178 : QGraphicsObject(*new QGraphicsWidgetPrivate, 0, 0), QGraphicsLayoutItem(0, false)
180 Q_D(QGraphicsWidget);
181 d->init(parent, wFlags);
187 Constructs a new QGraphicsWidget, using \a dd as parent.
189 QGraphicsWidget::QGraphicsWidget(QGraphicsWidgetPrivate &dd, QGraphicsItem *parent, QGraphicsScene *scene, Qt::WindowFlags wFlags)
190 : QGraphicsObject(dd, 0, scene), QGraphicsLayoutItem(0, false)
192 Q_D(QGraphicsWidget);
193 d->init(parent, wFlags);
198 \class QGraphicsWidgetStyles
200 We use this thread-safe class to maintain a hash of styles for widgets
201 styles. Note that QApplication::style() itself isn't thread-safe, QStyle
202 isn't thread-safe, and we don't have a thread-safe factory for creating
203 the default style, nor cloning a style.
205 class QGraphicsWidgetStyles
208 QStyle *styleForWidget(const QGraphicsWidget *widget) const
210 QMutexLocker locker(&mutex);
211 return styles.value(widget, 0);
214 void setStyleForWidget(QGraphicsWidget *widget, QStyle *style)
216 QMutexLocker locker(&mutex);
218 styles[widget] = style;
220 styles.remove(widget);
224 QMap<const QGraphicsWidget *, QStyle *> styles;
225 mutable QMutex mutex;
227 Q_GLOBAL_STATIC(QGraphicsWidgetStyles, widgetStyles)
230 Destroys the QGraphicsWidget instance.
232 QGraphicsWidget::~QGraphicsWidget()
234 Q_D(QGraphicsWidget);
236 // Remove all actions from this widget
237 for (int i = 0; i < d->actions.size(); ++i) {
238 QActionPrivate *apriv = d->actions.at(i)->d_func();
239 apriv->graphicsWidgets.removeAll(this);
244 if (QGraphicsScene *scn = scene()) {
245 QGraphicsScenePrivate *sceneD = scn->d_func();
246 if (sceneD->tabFocusFirst == this)
247 sceneD->tabFocusFirst = (d->focusNext == this ? 0 : d->focusNext);
249 d->focusPrev->d_func()->focusNext = d->focusNext;
250 d->focusNext->d_func()->focusPrev = d->focusPrev;
252 // Play it really safe
258 //we check if we have a layout previously
260 QGraphicsLayout *temp = d->layout;
261 foreach (QGraphicsItem * item, childItems()) {
262 // In case of a custom layout which doesn't remove and delete items, we ensure that
263 // the parent layout item does not point to the deleted layout. This code is here to
264 // avoid regression from 4.4 to 4.5, because according to 4.5 docs it is not really needed.
265 if (item->isWidget()) {
266 QGraphicsWidget *widget = static_cast<QGraphicsWidget *>(item);
267 if (widget->parentLayoutItem() == d->layout)
268 widget->setParentLayoutItem(0);
275 // Remove this graphics widget from widgetStyles
276 widgetStyles()->setStyleForWidget(this, 0);
280 \property QGraphicsWidget::size
281 \brief the size of the widget
283 Calling resize() resizes the widget to a \a size bounded by minimumSize()
284 and maximumSize(). This property only affects the widget's width and
285 height (e.g., its right and bottom edges); the widget's position and
286 top-left corner remains unaffected.
288 Resizing a widget triggers the widget to immediately receive a
289 \l{QEvent::GraphicsSceneResize}{GraphicsSceneResize} event with the
290 widget's old and new size. If the widget has a layout assigned when this
291 event arrives, the layout will be activated and it will automatically
292 update any child widgets's geometry.
294 This property does not affect any layout of the parent widget. If the
295 widget itself is managed by a parent layout; e.g., it has a parent widget
296 with a layout assigned, that layout will not activate.
298 By default, this property contains a size with zero width and height.
300 \sa setGeometry(), QGraphicsSceneResizeEvent, QGraphicsLayout
302 QSizeF QGraphicsWidget::size() const
304 return QGraphicsLayoutItem::geometry().size();
307 void QGraphicsWidget::resize(const QSizeF &size)
309 setGeometry(QRectF(pos(), size));
313 \fn void QGraphicsWidget::resize(qreal w, qreal h)
315 This convenience function is equivalent to calling resize(QSizeF(w, h)).
317 \sa setGeometry(), setTransform()
321 \property QGraphicsWidget::sizePolicy
322 \brief the size policy for the widget
323 \sa sizePolicy(), setSizePolicy(), QWidget::sizePolicy()
327 \fn QGraphicsWidget::geometryChanged()
329 This signal gets emitted whenever the geometry is changed in setGeometry().
333 \property QGraphicsWidget::geometry
334 \brief the geometry of the widget
336 Sets the item's geometry to \a rect. The item's position and size are
337 modified as a result of calling this function. The item is first moved,
340 A side effect of calling this function is that the widget will receive
341 a move event and a resize event. Also, if the widget has a layout
342 assigned, the layout will activate.
344 \sa geometry(), resize()
346 void QGraphicsWidget::setGeometry(const QRectF &rect)
348 QGraphicsWidgetPrivate *wd = QGraphicsWidget::d_func();
349 QGraphicsLayoutItemPrivate *d = QGraphicsLayoutItem::d_ptr.data();
351 QPointF oldPos = d->geom.topLeft();
353 setAttribute(Qt::WA_Resized);
355 newGeom.setSize(rect.size().expandedTo(effectiveSizeHint(Qt::MinimumSize))
356 .boundedTo(effectiveSizeHint(Qt::MaximumSize)));
357 if (newGeom == d->geom)
360 // setPos triggers ItemPositionChange, which can adjust position
361 wd->inSetGeometry = 1;
362 setPos(newGeom.topLeft());
363 wd->inSetGeometry = 0;
364 newGeom.moveTopLeft(pos());
366 if (newGeom == d->geom)
369 // Update and prepare to change the geometry (remove from index) if the size has changed.
371 if (rect.topLeft() == d->geom.topLeft()) {
372 prepareGeometryChange();
377 // Update the layout item geometry
378 bool moved = oldPos != pos();
381 QGraphicsSceneMoveEvent event;
382 event.setOldPos(oldPos);
383 event.setNewPos(pos());
384 QApplication::sendEvent(this, &event);
387 d->geom.moveTopLeft(pos());
388 emit geometryChanged();
392 QSizeF oldSize = size();
393 QGraphicsLayoutItem::setGeometry(newGeom);
395 bool resized = newGeom.size() != oldSize;
397 QGraphicsSceneResizeEvent re;
398 re.setOldSize(oldSize);
399 re.setNewSize(newGeom.size());
400 if (oldSize.width() != newGeom.size().width())
402 if (oldSize.height() != newGeom.size().height())
403 emit heightChanged();
404 QApplication::sendEvent(this, &re);
406 emit geometryChanged();
410 \fn QRectF QGraphicsWidget::rect() const
412 Returns the item's local rect as a QRectF. This function is equivalent
413 to QRectF(QPointF(), size()).
415 \sa setGeometry(), resize()
419 \fn void QGraphicsWidget::setGeometry(qreal x, qreal y, qreal w, qreal h)
421 This convenience function is equivalent to calling setGeometry(QRectF(
422 \a x, \a y, \a w, \a h)).
424 \sa geometry(), resize()
428 \property QGraphicsWidget::minimumSize
429 \brief the minimum size of the widget
431 \sa setMinimumSize(), minimumSize(), preferredSize, maximumSize
435 \property QGraphicsWidget::preferredSize
436 \brief the preferred size of the widget
438 \sa setPreferredSize(), preferredSize(), minimumSize, maximumSize
442 \property QGraphicsWidget::maximumSize
443 \brief the maximum size of the widget
445 \sa setMaximumSize(), maximumSize(), minimumSize, preferredSize
449 Sets the widget's contents margins to \a left, \a top, \a right and \a
452 Contents margins are used by the assigned layout to define the placement
453 of subwidgets and layouts. Margins are particularly useful for widgets
454 that constrain subwidgets to only a section of its own geometry. For
455 example, a group box with a layout will place subwidgets inside its frame,
458 Changing a widget's contents margins will always trigger an update(), and
459 any assigned layout will be activated automatically. The widget will then
460 receive a \l{QEvent::ContentsRectChange}{ContentsRectChange} event.
462 \sa getContentsMargins(), setGeometry()
464 void QGraphicsWidget::setContentsMargins(qreal left, qreal top, qreal right, qreal bottom)
466 Q_D(QGraphicsWidget);
468 if (!d->margins && left == 0 && top == 0 && right == 0 && bottom == 0)
471 if (left == d->margins[d->Left]
472 && top == d->margins[d->Top]
473 && right == d->margins[d->Right]
474 && bottom == d->margins[d->Bottom])
477 d->margins[d->Left] = left;
478 d->margins[d->Top] = top;
479 d->margins[d->Right] = right;
480 d->margins[d->Bottom] = bottom;
482 if (QGraphicsLayout *l = d->layout)
487 QEvent e(QEvent::ContentsRectChange);
488 QApplication::sendEvent(this, &e);
492 Gets the widget's contents margins. The margins are stored in \a left, \a
493 top, \a right and \a bottom, as pointers to qreals. Each argument can
494 be \e {omitted} by passing 0.
496 \sa setContentsMargins()
498 void QGraphicsWidget::getContentsMargins(qreal *left, qreal *top, qreal *right, qreal *bottom) const
500 Q_D(const QGraphicsWidget);
501 if (left || top || right || bottom)
504 *left = d->margins[d->Left];
506 *top = d->margins[d->Top];
508 *right = d->margins[d->Right];
510 *bottom = d->margins[d->Bottom];
514 Sets the widget's window frame margins to \a left, \a top, \a right and
515 \a bottom. The default frame margins are provided by the style, and they
516 depend on the current window flags.
518 If you would like to draw your own window decoration, you can set your
519 own frame margins to override the default margins.
521 \sa unsetWindowFrameMargins(), getWindowFrameMargins(), windowFrameRect()
523 void QGraphicsWidget::setWindowFrameMargins(qreal left, qreal top, qreal right, qreal bottom)
525 Q_D(QGraphicsWidget);
527 if (!d->windowFrameMargins && left == 0 && top == 0 && right == 0 && bottom == 0)
529 d->ensureWindowFrameMargins();
531 d->windowFrameMargins[d->Left] == left
532 && d->windowFrameMargins[d->Top] == top
533 && d->windowFrameMargins[d->Right] == right
534 && d->windowFrameMargins[d->Bottom] == bottom;
535 if (d->setWindowFrameMargins && unchanged)
538 prepareGeometryChange();
539 d->windowFrameMargins[d->Left] = left;
540 d->windowFrameMargins[d->Top] = top;
541 d->windowFrameMargins[d->Right] = right;
542 d->windowFrameMargins[d->Bottom] = bottom;
543 d->setWindowFrameMargins = true;
547 Gets the widget's window frame margins. The margins are stored in \a left,
548 \a top, \a right and \a bottom as pointers to qreals. Each argument can
549 be \e {omitted} by passing 0.
551 \sa setWindowFrameMargins(), windowFrameRect()
553 void QGraphicsWidget::getWindowFrameMargins(qreal *left, qreal *top, qreal *right, qreal *bottom) const
555 Q_D(const QGraphicsWidget);
556 if (left || top || right || bottom)
557 d->ensureWindowFrameMargins();
559 *left = d->windowFrameMargins[d->Left];
561 *top = d->windowFrameMargins[d->Top];
563 *right = d->windowFrameMargins[d->Right];
565 *bottom = d->windowFrameMargins[d->Bottom];
569 Resets the window frame margins to the default value, provided by the style.
571 \sa setWindowFrameMargins(), getWindowFrameMargins(), windowFrameRect()
573 void QGraphicsWidget::unsetWindowFrameMargins()
575 Q_D(QGraphicsWidget);
576 if ((d->windowFlags & Qt::Window) && (d->windowFlags & Qt::WindowType_Mask) != Qt::Popup &&
577 (d->windowFlags & Qt::WindowType_Mask) != Qt::ToolTip && !(d->windowFlags & Qt::FramelessWindowHint)) {
578 QStyleOptionTitleBar bar;
579 d->initStyleOptionTitleBar(&bar);
580 QStyle *style = this->style();
581 qreal margin = style->pixelMetric(QStyle::PM_MdiSubWindowFrameWidth);
582 qreal titleBarHeight = d->titleBarHeight(bar);
583 setWindowFrameMargins(margin, titleBarHeight, margin, margin);
585 setWindowFrameMargins(0, 0, 0, 0);
587 d->setWindowFrameMargins = false;
591 Returns the widget's geometry in parent coordinates including any window
594 \sa windowFrameRect(), getWindowFrameMargins(), setWindowFrameMargins()
596 QRectF QGraphicsWidget::windowFrameGeometry() const
598 Q_D(const QGraphicsWidget);
599 return d->windowFrameMargins
600 ? geometry().adjusted(-d->windowFrameMargins[d->Left], -d->windowFrameMargins[d->Top],
601 d->windowFrameMargins[d->Right], d->windowFrameMargins[d->Bottom])
606 Returns the widget's local rect including any window frame.
608 \sa windowFrameGeometry(), getWindowFrameMargins(), setWindowFrameMargins()
610 QRectF QGraphicsWidget::windowFrameRect() const
612 Q_D(const QGraphicsWidget);
613 return d->windowFrameMargins
614 ? rect().adjusted(-d->windowFrameMargins[d->Left], -d->windowFrameMargins[d->Top],
615 d->windowFrameMargins[d->Right], d->windowFrameMargins[d->Bottom])
620 Populates a style option object for this widget based on its current
621 state, and stores the output in \a option. The default implementation
622 populates \a option with the following properties.
626 \o Style Option Property
629 \o state & QStyle::State_Enabled
630 \o Corresponds to QGraphicsItem::isEnabled().
632 \o state & QStyle::State_HasFocus
633 \o Corresponds to QGraphicsItem::hasFocus().
635 \o state & QStyle::State_MouseOver
636 \o Corresponds to QGraphicsItem::isUnderMouse().
639 \o Corresponds to QGraphicsWidget::layoutDirection().
642 \o Corresponds to QGraphicsWidget::rect().toRect().
645 \o Corresponds to QGraphicsWidget::palette().
648 \o Corresponds to QFontMetrics(QGraphicsWidget::font()).
651 Subclasses of QGraphicsWidget should call the base implementation, and
652 then test the type of \a option using qstyleoption_cast<>() or test
653 QStyleOption::Type before storing widget-specific options.
657 \snippet doc/src/snippets/code/src_gui_graphicsview_qgraphicswidget.cpp 0
659 \sa QStyleOption::initFrom()
661 void QGraphicsWidget::initStyleOption(QStyleOption *option) const
665 option->state = QStyle::State_None;
667 option->state |= QStyle::State_Enabled;
669 option->state |= QStyle::State_HasFocus;
670 // if (window->testAttribute(Qt::WA_KeyboardFocusChange)) // ### Window
671 // option->state |= QStyle::State_KeyboardFocusChange;
673 option->state |= QStyle::State_MouseOver;
674 if (QGraphicsWidget *w = window()) {
675 if (w->isActiveWindow())
676 option->state |= QStyle::State_Active;
679 option->state |= QStyle::State_Window;
683 extern bool qt_mac_can_clickThrough(const QGraphicsWidget *w); //qwidget_mac.cpp
684 if (!(option->state & QStyle::State_Active) && !qt_mac_can_clickThrough(widget))
685 option->state &= ~QStyle::State_Enabled;
687 switch (QMacStyle::widgetSizePolicy(widget)) {
688 case QMacStyle::SizeSmall:
689 option->state |= QStyle::State_Small;
691 case QMacStyle::SizeMini:
692 option->state |= QStyle::State_Mini;
698 #ifdef QT_KEYPAD_NAVIGATION
699 if (widget->hasEditFocus())
700 state |= QStyle::State_HasEditFocus;
703 option->direction = layoutDirection();
704 option->rect = rect().toRect(); // ### truncation!
705 option->palette = palette();
707 option->palette.setCurrentColorGroup(QPalette::Disabled);
708 } else if (isActiveWindow()) {
709 option->palette.setCurrentColorGroup(QPalette::Active);
711 option->palette.setCurrentColorGroup(QPalette::Inactive);
713 option->fontMetrics = QFontMetrics(font());
719 QSizeF QGraphicsWidget::sizeHint(Qt::SizeHint which, const QSizeF &constraint) const
721 Q_D(const QGraphicsWidget);
724 QSizeF marginSize(0,0);
726 marginSize = QSizeF(d->margins[d->Left] + d->margins[d->Right],
727 d->margins[d->Top] + d->margins[d->Bottom]);
729 sh = d->layout->effectiveSizeHint(which, constraint - marginSize);
733 case Qt::MinimumSize:
736 case Qt::PreferredSize:
737 sh = QSizeF(50, 50); //rather arbitrary
739 case Qt::MaximumSize:
740 sh = QSizeF(QWIDGETSIZE_MAX, QWIDGETSIZE_MAX);
743 qWarning("QGraphicsWidget::sizeHint(): Don't know how to handle the value of 'which'");
751 \property QGraphicsWidget::layout
752 \brief The layout of the widget
754 Any existing layout manager is deleted before the new layout is assigned. If
755 \a layout is 0, the widget is left without a layout. Existing subwidgets'
756 geometries will remain unaffected.
758 QGraphicsWidget takes ownership of \a layout.
760 All widgets that are currently managed by \a layout or all of its
761 sublayouts, are automatically reparented to this item. The layout is then
762 invalidated, and the child widget geometries are adjusted according to
763 this item's geometry() and contentsMargins(). Children who are not
764 explicitly managed by \a layout remain unaffected by the layout after
765 it has been assigned to this widget.
767 If no layout is currently managing this widget, layout() will return 0.
772 \fn void QGraphicsWidget::layoutChanged()
773 This signal gets emitted whenever the layout of the item changes
778 Returns this widget's layout, or 0 if no layout is currently managing this
783 QGraphicsLayout *QGraphicsWidget::layout() const
785 Q_D(const QGraphicsWidget);
790 \fn void QGraphicsWidget::setLayout(QGraphicsLayout *layout)
792 Sets the layout for this widget to \a layout. Any existing layout manager
793 is deleted before the new layout is assigned. If \a layout is 0, the
794 widget is left without a layout. Existing subwidgets' geometries will
797 All widgets that are currently managed by \a layout or all of its
798 sublayouts, are automatically reparented to this item. The layout is then
799 invalidated, and the child widget geometries are adjusted according to
800 this item's geometry() and contentsMargins(). Children who are not
801 explicitly managed by \a layout remain unaffected by the layout after
802 it has been assigned to this widget.
804 QGraphicsWidget takes ownership of \a layout.
806 \sa layout(), QGraphicsLinearLayout::addItem(), QGraphicsLayout::invalidate()
808 void QGraphicsWidget::setLayout(QGraphicsLayout *l)
810 Q_D(QGraphicsWidget);
813 d->setLayout_helper(l);
817 // Prevent assigning a layout that is already assigned to another widget.
818 QGraphicsLayoutItem *oldParent = l->parentLayoutItem();
819 if (oldParent && oldParent != this) {
820 qWarning("QGraphicsWidget::setLayout: Attempting to set a layout on %s"
821 " \"%s\", when the layout already has a parent",
822 metaObject()->className(), qPrintable(objectName()));
826 // Install and activate the layout.
827 l->setParentLayoutItem(this);
828 l->d_func()->reparentChildItems(this);
830 emit layoutChanged();
834 Adjusts the size of the widget to its effective preferred size hint.
836 This function is called implicitly when the item is shown for the first
839 \sa effectiveSizeHint(), Qt::MinimumSize
841 void QGraphicsWidget::adjustSize()
843 QSizeF sz = effectiveSizeHint(Qt::PreferredSize);
844 // What if sz is not valid?!
850 \property QGraphicsWidget::layoutDirection
851 \brief the layout direction for this widget.
853 This property modifies this widget's and all of its descendants'
854 Qt::WA_RightToLeft attribute. It also sets this widget's
855 Qt::WA_SetLayoutDirection attribute.
857 The widget's layout direction determines the order in which the layout
858 manager horizontally arranges subwidgets of this widget. The default
859 value depends on the language and locale of the application, and is
860 typically in the same direction as words are read and written. With
861 Qt::LeftToRight, the layout starts placing subwidgets from the left
862 side of this widget towards the right. Qt::RightToLeft does the opposite -
863 the layout will place widgets starting from the right edge moving towards
866 Subwidgets inherit their layout direction from the parent. Top-level
867 widget items inherit their layout direction from
868 QGraphicsScene::layoutDirection. If you change a widget's layout direction
869 by calling setLayoutDirection(), the widget will send itself a
870 \l{QEvent::LayoutDirectionChange}{LayoutDirectionChange} event, and then
871 propagate the new layout direction to all its descendants.
873 \sa QWidget::layoutDirection, QApplication::layoutDirection
875 Qt::LayoutDirection QGraphicsWidget::layoutDirection() const
877 return testAttribute(Qt::WA_RightToLeft) ? Qt::RightToLeft : Qt::LeftToRight;
879 void QGraphicsWidget::setLayoutDirection(Qt::LayoutDirection direction)
881 Q_D(QGraphicsWidget);
882 setAttribute(Qt::WA_SetLayoutDirection, true);
883 d->setLayoutDirection_helper(direction);
885 void QGraphicsWidget::unsetLayoutDirection()
887 Q_D(QGraphicsWidget);
888 setAttribute(Qt::WA_SetLayoutDirection, false);
889 d->resolveLayoutDirection();
893 Returns a pointer to the widget's style. If this widget does not have any
894 explicitly assigned style, the scene's style is returned instead. In turn,
895 if the scene does not have any assigned style, this function returns
896 QApplication::style().
900 QStyle *QGraphicsWidget::style() const
902 if (QStyle *style = widgetStyles()->styleForWidget(this))
904 // ### This is not thread-safe. QApplication::style() is not thread-safe.
905 return scene() ? scene()->style() : QApplication::style();
909 Sets the widget's style to \a style. QGraphicsWidget does \e not take
910 ownership of \a style.
912 If no style is assigned, or \a style is 0, the widget will use
913 QGraphicsScene::style() (if this has been set). Otherwise the widget will
914 use QApplication::style().
916 This function sets the Qt::WA_SetStyle attribute if \a style is not 0;
917 otherwise it clears the attribute.
921 void QGraphicsWidget::setStyle(QStyle *style)
923 setAttribute(Qt::WA_SetStyle, style != 0);
924 widgetStyles()->setStyleForWidget(this, style);
926 // Deliver StyleChange to the widget itself (doesn't propagate).
927 QEvent event(QEvent::StyleChange);
928 QApplication::sendEvent(this, &event);
932 \property QGraphicsWidget::font
933 \brief the widgets' font
935 This property provides the widget's font.
937 QFont consists of font properties that have been explicitly defined and
938 properties implicitly inherited from the widget's parent. Hence, font()
939 can return a different font compared to the one set with setFont().
940 This scheme allows you to define single entries in a font without
941 affecting the font's inherited entries.
943 When a widget's font changes, it resolves its entries against its
944 parent widget. If the widget does not have a parent widget, it resolves
945 its entries against the scene. The widget then sends itself a
946 \l{QEvent::FontChange}{FontChange} event and notifies all its
947 descendants so that they can resolve their fonts as well.
949 By default, this property contains the application's default font.
951 \sa QApplication::font(), QGraphicsScene::font, QFont::resolve()
953 QFont QGraphicsWidget::font() const
955 Q_D(const QGraphicsWidget);
957 fnt.resolve(fnt.resolve() | d->inheritedFontResolveMask);
960 void QGraphicsWidget::setFont(const QFont &font)
962 Q_D(QGraphicsWidget);
963 setAttribute(Qt::WA_SetFont, font.resolve() != 0);
965 QFont naturalFont = d->naturalWidgetFont();
966 QFont resolvedFont = font.resolve(naturalFont);
967 d->setFont_helper(resolvedFont);
971 \property QGraphicsWidget::palette
972 \brief the widget's palette
974 This property provides the widget's palette. The palette provides colors
975 and brushes for color groups (e.g., QPalette::Button) and states (e.g.,
976 QPalette::Inactive), loosely defining the general look of the widget and
979 QPalette consists of color groups that have been explicitly defined, and
980 groups that are implicitly inherited from the widget's parent. Because of
981 this, palette() can return a different palette than what has been set with
982 setPalette(). This scheme allows you to define single entries in a palette
983 without affecting the palette's inherited entries.
985 When a widget's palette changes, it resolves its entries against its
986 parent widget, or if it doesn't have a parent widget, it resolves against
987 the scene. It then sends itself a \l{QEvent::PaletteChange}{PaletteChange}
988 event, and notifies all its descendants so they can resolve their palettes
991 By default, this property contains the application's default palette.
993 \sa QApplication::palette(), QGraphicsScene::palette, QPalette::resolve()
995 QPalette QGraphicsWidget::palette() const
997 Q_D(const QGraphicsWidget);
1000 void QGraphicsWidget::setPalette(const QPalette &palette)
1002 Q_D(QGraphicsWidget);
1003 setAttribute(Qt::WA_SetPalette, palette.resolve() != 0);
1005 QPalette naturalPalette = d->naturalWidgetPalette();
1006 QPalette resolvedPalette = palette.resolve(naturalPalette);
1007 d->setPalette_helper(resolvedPalette);
1011 \property QGraphicsWidget::autoFillBackground
1012 \brief whether the widget background is filled automatically
1015 If enabled, this property will cause Qt to fill the background of the
1016 widget before invoking the paint() method. The color used is defined by the
1017 QPalette::Window color role from the widget's \l{QPalette}{palette}.
1019 In addition, Windows are always filled with QPalette::Window, unless the
1020 WA_OpaquePaintEvent or WA_NoSystemBackground attributes are set.
1022 By default, this property is false.
1024 \sa Qt::WA_OpaquePaintEvent, Qt::WA_NoSystemBackground,
1026 bool QGraphicsWidget::autoFillBackground() const
1028 Q_D(const QGraphicsWidget);
1029 return d->autoFillBackground;
1031 void QGraphicsWidget::setAutoFillBackground(bool enabled)
1033 Q_D(QGraphicsWidget);
1034 if (d->autoFillBackground != enabled) {
1035 d->autoFillBackground = enabled;
1041 If this widget is currently managed by a layout, this function notifies
1042 the layout that the widget's size hints have changed and the layout
1043 may need to resize and reposition the widget accordingly.
1045 Call this function if the widget's sizeHint() has changed.
1047 \sa QGraphicsLayout::invalidate()
1049 void QGraphicsWidget::updateGeometry()
1051 QGraphicsLayoutItem::updateGeometry();
1052 QGraphicsLayoutItem *parentItem = parentLayoutItem();
1054 if (parentItem && parentItem->isLayout()) {
1055 parentItem->updateGeometry();
1058 QGraphicsWidget *parentWid = parentWidget(); //###
1059 if (parentWid->isVisible())
1060 QApplication::postEvent(parentWid, new QEvent(QEvent::LayoutRequest));
1062 bool wasResized = testAttribute(Qt::WA_Resized);
1063 resize(size()); // this will restrict the size
1064 setAttribute(Qt::WA_Resized, wasResized);
1071 QGraphicsWidget uses the base implementation of this function to catch and
1072 deliver events related to state changes in the item. Because of this, it is
1073 very important that subclasses call the base implementation.
1075 \a change specifies the type of change, and \a value is the new value.
1077 For example, QGraphicsWidget uses ItemVisibleChange to deliver
1078 \l{QEvent::Show} {Show} and \l{QEvent::Hide}{Hide} events,
1079 ItemPositionHasChanged to deliver \l{QEvent::Move}{Move} events,
1080 and ItemParentChange both to deliver \l{QEvent::ParentChange}
1081 {ParentChange} events, and for managing the focus chain.
1083 QGraphicsWidget enables the ItemSendsGeometryChanges flag by default in
1084 order to track position changes.
1086 \sa QGraphicsItem::itemChange()
1088 QVariant QGraphicsWidget::itemChange(GraphicsItemChange change, const QVariant &value)
1090 Q_D(QGraphicsWidget);
1092 case ItemEnabledHasChanged: {
1093 // Send EnabledChange after the enabled state has changed.
1094 QEvent event(QEvent::EnabledChange);
1095 QApplication::sendEvent(this, &event);
1098 case ItemVisibleChange:
1099 if (value.toBool()) {
1100 // Send Show event before the item has been shown.
1102 QApplication::sendEvent(this, &event);
1103 bool resized = testAttribute(Qt::WA_Resized);
1106 setAttribute(Qt::WA_Resized, false);
1110 case ItemVisibleHasChanged:
1111 if (!value.toBool()) {
1112 // Send Hide event after the item has been hidden.
1114 QApplication::sendEvent(this, &event);
1117 case ItemPositionHasChanged:
1118 d->setGeometryFromSetPos();
1120 case ItemParentChange: {
1121 // Deliver ParentAboutToChange.
1122 QEvent event(QEvent::ParentAboutToChange);
1123 QApplication::sendEvent(this, &event);
1126 case ItemParentHasChanged: {
1127 // Deliver ParentChange.
1128 QEvent event(QEvent::ParentChange);
1129 QApplication::sendEvent(this, &event);
1132 case ItemCursorHasChanged: {
1133 // Deliver CursorChange.
1134 QEvent event(QEvent::CursorChange);
1135 QApplication::sendEvent(this, &event);
1138 case ItemToolTipHasChanged: {
1139 // Deliver ToolTipChange.
1140 QEvent event(QEvent::ToolTipChange);
1141 QApplication::sendEvent(this, &event);
1147 return QGraphicsItem::itemChange(change, value);
1153 This virtual function is used to notify changes to any property (both
1154 dynamic properties, and registered with Q_PROPERTY) in the
1155 widget. Depending on the property itself, the notification can be
1156 delivered before or after the value has changed.
1158 \a propertyName is the name of the property (e.g., "size" or "font"), and
1159 \a value is the (proposed) new value of the property. The function returns
1160 the new value, which may be different from \a value if the notification
1161 supports adjusting the property value. The base implementation simply
1162 returns \a value for any \a propertyName.
1164 QGraphicsWidget delivers notifications for the following properties:
1166 \table \o propertyName \o Property
1167 \row \o layoutDirection \o QGraphicsWidget::layoutDirection
1168 \row \o size \o QGraphicsWidget::size
1169 \row \o font \o QGraphicsWidget::font
1170 \row \o palette \o QGraphicsWidget::palette
1175 QVariant QGraphicsWidget::propertyChange(const QString &propertyName, const QVariant &value)
1177 Q_UNUSED(propertyName);
1182 QGraphicsWidget's implementation of sceneEvent() simply passes \a event to
1183 QGraphicsWidget::event(). You can handle all events for your widget in
1184 event() or in any of the convenience functions; you should not have to
1185 reimplement this function in a subclass of QGraphicsWidget.
1187 \sa QGraphicsItem::sceneEvent()
1189 bool QGraphicsWidget::sceneEvent(QEvent *event)
1191 return QGraphicsItem::sceneEvent(event);
1195 This event handler, for \a event, receives events for the window frame if
1196 this widget is a window. Its base implementation provides support for
1197 default window frame interaction such as moving, resizing, etc.
1199 You can reimplement this handler in a subclass of QGraphicsWidget to
1200 provide your own custom window frame interaction support.
1202 Returns true if \a event has been recognized and processed; otherwise,
1207 bool 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();
1239 Returns the window frame section at position \a pos, or
1240 Qt::NoSection if there is no window frame section at this
1243 This function is used in QGraphicsWidget's base implementation for window
1246 You can reimplement this function if you want to customize how a window
1247 can be interactively moved or resized. For instance, if you only want to
1248 allow a window to be resized by the bottom right corner, you can
1249 reimplement this function to return Qt::NoSection for all sections except
1250 Qt::BottomRightSection.
1252 \sa windowFrameEvent(), paintWindowFrame(), windowFrameGeometry()
1254 Qt::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;
1270 //### Not sure of this one, it should be the same value for all edges.
1271 const qreal windowFrameWidth = d->windowFrameMargins
1272 ? d->windowFrameMargins[d->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 - windowFrameWidth)) {
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 - windowFrameWidth)) {
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[d->Top] : 0);
1300 if (r1.contains(pos))
1301 s = Qt::TitleBarArea;
1309 Handles the \a event. QGraphicsWidget handles the following
1312 \table \o Event \o Usage
1314 \o Delivered to the widget some time after it has been
1316 \row \o GraphicsSceneMove
1317 \o Delivered to the widget after its local position has
1319 \row \o GraphicsSceneResize
1320 \o Delivered to the widget after its size has changed.
1322 \o Delivered to the widget before it has been shown.
1324 \o Delivered to the widget after it has been hidden.
1325 \row \o PaletteChange
1326 \o Delivered to the widget after its palette has changed.
1328 \o Delivered to the widget after its font has changed.
1329 \row \o EnabledChange
1330 \o Delivered to the widget after its enabled state has
1333 \o Delivered to the widget after its style has changed.
1334 \row \o LayoutDirectionChange
1335 \o Delivered to the widget after its layout direction has
1337 \row \o ContentsRectChange
1338 \o Delivered to the widget after its contents margins/
1339 contents rect has changed.
1342 bool QGraphicsWidget::event(QEvent *event)
1344 Q_D(QGraphicsWidget);
1345 // Forward the event to the layout first.
1347 d->layout->widgetEvent(event);
1349 // Handle the event itself.
1350 switch (event->type()) {
1351 case QEvent::GraphicsSceneMove:
1352 moveEvent(static_cast<QGraphicsSceneMoveEvent *>(event));
1354 case QEvent::GraphicsSceneResize:
1355 resizeEvent(static_cast<QGraphicsSceneResizeEvent *>(event));
1358 showEvent(static_cast<QShowEvent *>(event));
1361 hideEvent(static_cast<QHideEvent *>(event));
1363 case QEvent::Polish:
1366 if (!d->font.isCopyOf(QApplication::font()))
1367 d->updateFont(d->font);
1369 case QEvent::WindowActivate:
1370 case QEvent::WindowDeactivate:
1373 // Taken from QWidget::event
1374 case QEvent::ActivationChange:
1375 case QEvent::EnabledChange:
1376 case QEvent::FontChange:
1377 case QEvent::StyleChange:
1378 case QEvent::PaletteChange:
1379 case QEvent::ParentChange:
1380 case QEvent::ContentsRectChange:
1381 case QEvent::LayoutDirectionChange:
1385 closeEvent((QCloseEvent *)event);
1387 case QEvent::GrabMouse:
1388 grabMouseEvent(event);
1390 case QEvent::UngrabMouse:
1391 ungrabMouseEvent(event);
1393 case QEvent::GrabKeyboard:
1394 grabKeyboardEvent(event);
1396 case QEvent::UngrabKeyboard:
1397 ungrabKeyboardEvent(event);
1399 case QEvent::GraphicsSceneMousePress:
1400 if (d->hasDecoration() && windowFrameEvent(event))
1402 case QEvent::GraphicsSceneMouseMove:
1403 case QEvent::GraphicsSceneMouseRelease:
1404 case QEvent::GraphicsSceneMouseDoubleClick:
1405 d->ensureWindowData();
1406 if (d->hasDecoration() && d->windowData->grabbedSection != Qt::NoSection)
1407 return windowFrameEvent(event);
1409 case QEvent::GraphicsSceneHoverEnter:
1410 case QEvent::GraphicsSceneHoverMove:
1411 case QEvent::GraphicsSceneHoverLeave:
1412 if (d->hasDecoration()) {
1413 windowFrameEvent(event);
1414 // Filter out hover events if they were sent to us only because of the
1415 // decoration (special case in QGraphicsScenePrivate::dispatchHoverEvent).
1416 if (!acceptsHoverEvents())
1423 return QObject::event(event);
1427 This event handler can be reimplemented to handle state changes.
1429 The state being changed in this event can be retrieved through \a event.
1431 Change events include: QEvent::ActivationChange, QEvent::EnabledChange,
1432 QEvent::FontChange, QEvent::StyleChange, QEvent::PaletteChange,
1433 QEvent::ParentChange, QEvent::LayoutDirectionChange, and
1434 QEvent::ContentsRectChange.
1436 void QGraphicsWidget::changeEvent(QEvent *event)
1438 Q_D(QGraphicsWidget);
1439 switch (event->type()) {
1440 case QEvent::StyleChange:
1441 // ### Don't unset if the margins are explicitly set.
1442 unsetWindowFrameMargins();
1444 d->layout->invalidate();
1445 case QEvent::FontChange:
1449 case QEvent::PaletteChange:
1452 case QEvent::ParentChange:
1453 d->resolveFont(d->inheritedFontResolveMask);
1454 d->resolvePalette(d->inheritedPaletteResolveMask);
1462 This event handler, for \a event, can be reimplemented in a subclass to
1463 receive widget close events. The default implementation accepts the
1466 \sa close(), QCloseEvent
1468 void QGraphicsWidget::closeEvent(QCloseEvent *event)
1476 void QGraphicsWidget::focusInEvent(QFocusEvent *event)
1479 if (focusPolicy() != Qt::NoFocus)
1484 Finds a new widget to give the keyboard focus to, as appropriate for Tab
1485 and Shift+Tab, and returns true if it can find a new widget; returns false
1486 otherwise. If \a next is true, this function searches forward; if \a next
1487 is false, it searches backward.
1489 Sometimes, you will want to reimplement this function to provide special
1490 focus handling for your widget and its subwidgets. For example, a web
1491 browser might reimplement it to move its current active link forward or
1492 backward, and call the base implementation only when it reaches the last
1493 or first link on the page.
1495 Child widgets call focusNextPrevChild() on their parent widgets, but only
1496 the window that contains the child widgets decides where to redirect
1497 focus. By reimplementing this function for an object, you gain control of
1498 focus traversal for all child widgets.
1502 bool QGraphicsWidget::focusNextPrevChild(bool next)
1504 Q_D(QGraphicsWidget);
1505 // Let the parent's focusNextPrevChild implementation decide what to do.
1506 QGraphicsWidget *parent = 0;
1507 if (!isWindow() && (parent = parentWidget()))
1508 return parent->focusNextPrevChild(next);
1511 if (d->scene->focusNextPrevChild(next))
1514 setFocus(next ? Qt::TabFocusReason : Qt::BacktabFocusReason);
1524 void QGraphicsWidget::focusOutEvent(QFocusEvent *event)
1527 if (focusPolicy() != Qt::NoFocus)
1532 This event handler, for \l{QEvent::Hide}{Hide} events, is delivered after
1533 the widget has been hidden, for example, setVisible(false) has been called
1534 for the widget or one of its ancestors when the widget was previously
1537 You can reimplement this event handler to detect when your widget is
1538 hidden. Calling QEvent::accept() or QEvent::ignore() on \a event has no
1541 \sa showEvent(), QWidget::hideEvent(), ItemVisibleChange
1543 void QGraphicsWidget::hideEvent(QHideEvent *event)
1545 ///### focusNextPrevChild(true), don't lose focus when the focus widget
1551 This event handler, for \l{QEvent::GraphicsSceneMove}{GraphicsSceneMove}
1552 events, is delivered after the widget has moved (e.g., its local position
1555 This event is only delivered when the item is moved locally. Calling
1556 setTransform() or moving any of the item's ancestors does not affect the
1557 item's local position.
1559 You can reimplement this event handler to detect when your widget has
1560 moved. Calling QEvent::accept() or QEvent::ignore() on \a event has no
1563 \sa ItemPositionChange, ItemPositionHasChanged
1565 void QGraphicsWidget::moveEvent(QGraphicsSceneMoveEvent *event)
1567 // ### Last position is always == current position
1572 This event is delivered to the item by the scene at some point after it
1573 has been constructed, but before it is shown or otherwise accessed through
1574 the scene. You can use this event handler to do last-minute initializations
1575 of the widget which require the item to be fully constructed.
1577 The base implementation does nothing.
1579 void QGraphicsWidget::polishEvent()
1584 This event handler, for
1585 \l{QEvent::GraphicsSceneResize}{GraphicsSceneResize} events, is
1586 delivered after the widget has been resized (i.e., its local size has
1587 changed). \a event contains both the old and the new size.
1589 This event is only delivered when the widget is resized locally; calling
1590 setTransform() on the widget or any of its ancestors or view, does not
1591 affect the widget's local size.
1593 You can reimplement this event handler to detect when your widget has been
1594 resized. Calling QEvent::accept() or QEvent::ignore() on \a event has no
1597 \sa geometry(), setGeometry()
1599 void QGraphicsWidget::resizeEvent(QGraphicsSceneResizeEvent *event)
1605 This event handler, for \l{QEvent::Show}{Show} events, is delivered before
1606 the widget has been shown, for example, setVisible(true) has been called
1607 for the widget or one of its ancestors when the widget was previously
1610 You can reimplement this event handler to detect when your widget is
1611 shown. Calling QEvent::accept() or QEvent::ignore() on \a event has no
1614 \sa hideEvent(), QWidget::showEvent(), ItemVisibleChange
1616 void QGraphicsWidget::showEvent(QShowEvent *event)
1624 void QGraphicsWidget::hoverMoveEvent(QGraphicsSceneHoverEvent *event)
1632 void QGraphicsWidget::hoverLeaveEvent(QGraphicsSceneHoverEvent *event)
1638 This event handler, for \a event, can be reimplemented in a subclass to
1639 receive notifications for Qt::GrabMouse events.
1641 \sa grabMouse(), grabKeyboard()
1643 void QGraphicsWidget::grabMouseEvent(QEvent *event)
1649 This event handler, for \a event, can be reimplemented in a subclass to
1650 receive notifications for Qt::UngrabMouse events.
1652 \sa ungrabMouse(), ungrabKeyboard()
1654 void QGraphicsWidget::ungrabMouseEvent(QEvent *event)
1660 This event handler, for \a event, can be reimplemented in a subclass to
1661 receive notifications for Qt::GrabKeyboard events.
1663 \sa grabKeyboard(), grabMouse()
1665 void QGraphicsWidget::grabKeyboardEvent(QEvent *event)
1671 This event handler, for \a event, can be reimplemented in a subclass to
1672 receive notifications for Qt::UngrabKeyboard events.
1674 \sa ungrabKeyboard(), ungrabMouse()
1676 void QGraphicsWidget::ungrabKeyboardEvent(QEvent *event)
1682 Returns the widgets window type.
1684 \sa windowFlags(), isWindow(), isPanel()
1686 Qt::WindowType QGraphicsWidget::windowType() const
1688 return Qt::WindowType(int(windowFlags()) & Qt::WindowType_Mask);
1692 \property QGraphicsWidget::windowFlags
1693 \brief the widget's window flags
1695 Window flags are a combination of a window type (e.g., Qt::Dialog) and
1696 several flags giving hints on the behavior of the window. The behavior
1697 is platform-dependent.
1699 By default, this property contains no window flags.
1701 Windows are panels. If you set the Qt::Window flag, the ItemIsPanel flag
1702 will be set automatically. If you clear the Qt::Window flag, the
1703 ItemIsPanel flag is also cleared. Note that the ItemIsPanel flag can be
1704 set independently of Qt::Window.
1706 \sa isWindow(), isPanel()
1708 Qt::WindowFlags QGraphicsWidget::windowFlags() const
1710 Q_D(const QGraphicsWidget);
1711 return d->windowFlags;
1713 void QGraphicsWidget::setWindowFlags(Qt::WindowFlags wFlags)
1715 Q_D(QGraphicsWidget);
1716 if (d->windowFlags == wFlags)
1718 bool wasPopup = (d->windowFlags & Qt::WindowType_Mask) == Qt::Popup;
1720 d->adjustWindowFlags(&wFlags);
1721 d->windowFlags = wFlags;
1722 if (!d->setWindowFrameMargins)
1723 unsetWindowFrameMargins();
1725 setFlag(ItemIsPanel, d->windowFlags & Qt::Window);
1727 bool isPopup = (d->windowFlags & Qt::WindowType_Mask) == Qt::Popup;
1728 if (d->scene && isVisible() && wasPopup != isPopup) {
1729 // Popup state changed; update implicit mouse grab.
1731 d->scene->d_func()->removePopup(this);
1733 d->scene->d_func()->addPopup(this);
1736 if (d->scene && d->scene->d_func()->allItemsIgnoreHoverEvents && d->hasDecoration()) {
1737 d->scene->d_func()->allItemsIgnoreHoverEvents = false;
1738 d->scene->d_func()->enableMouseTrackingOnViews();
1743 Returns true if this widget's window is in the active window, or if the
1744 widget does not have a window but is in an active scene (i.e., a scene
1745 that currently has focus).
1747 The active window is the window that either contains a child widget that
1748 currently has input focus, or that itself has input focus.
1750 \sa QGraphicsScene::activeWindow(), QGraphicsScene::setActiveWindow(), isActive()
1752 bool QGraphicsWidget::isActiveWindow() const
1758 \property QGraphicsWidget::windowTitle
1759 \brief This property holds the window title (caption).
1761 This property is only used for windows.
1763 By default, if no title has been set, this property contains an
1766 void QGraphicsWidget::setWindowTitle(const QString &title)
1768 Q_D(QGraphicsWidget);
1769 d->ensureWindowData();
1770 d->windowData->windowTitle = title;
1772 QString QGraphicsWidget::windowTitle() const
1774 Q_D(const QGraphicsWidget);
1775 return d->windowData ? d->windowData->windowTitle : QString();
1779 \property QGraphicsWidget::focusPolicy
1780 \brief the way the widget accepts keyboard focus
1782 The focus policy is Qt::TabFocus if the widget accepts keyboard focus by
1783 tabbing, Qt::ClickFocus if the widget accepts focus by clicking,
1784 Qt::StrongFocus if it accepts both, and Qt::NoFocus (the default) if it
1785 does not accept focus at all.
1787 You must enable keyboard focus for a widget if it processes keyboard
1788 events. This is normally done from the widget's constructor. For instance,
1789 the QLineEdit constructor calls setFocusPolicy(Qt::StrongFocus).
1791 If you enable a focus policy (i.e., not Qt::NoFocus), QGraphicsWidget will
1792 automatically enable the ItemIsFocusable flag. Setting Qt::NoFocus on a
1793 widget will clear the ItemIsFocusable flag. If the widget currently has
1794 keyboard focus, the widget will automatically lose focus.
1796 \sa focusInEvent(), focusOutEvent(), keyPressEvent(), keyReleaseEvent(), enabled
1798 Qt::FocusPolicy QGraphicsWidget::focusPolicy() const
1800 Q_D(const QGraphicsWidget);
1801 return d->focusPolicy;
1803 void QGraphicsWidget::setFocusPolicy(Qt::FocusPolicy policy)
1805 Q_D(QGraphicsWidget);
1806 if (d->focusPolicy == policy)
1808 d->focusPolicy = policy;
1809 if (hasFocus() && policy == Qt::NoFocus)
1811 setFlag(ItemIsFocusable, policy != Qt::NoFocus);
1815 If this widget, a child or descendant of this widget currently has input
1816 focus, this function will return a pointer to that widget. If
1817 no descendant widget has input focus, 0 is returned.
1819 \sa QGraphicsItem::focusItem(), QWidget::focusWidget()
1821 QGraphicsWidget *QGraphicsWidget::focusWidget() const
1823 Q_D(const QGraphicsWidget);
1824 if (d->subFocusItem && d->subFocusItem->d_ptr->isWidget)
1825 return static_cast<QGraphicsWidget *>(d->subFocusItem);
1829 #ifndef QT_NO_SHORTCUT
1833 Adds a shortcut to Qt's shortcut system that watches for the given key \a
1834 sequence in the given \a context. If the \a context is
1835 Qt::ApplicationShortcut, the shortcut applies to the application as a
1836 whole. Otherwise, it is either local to this widget, Qt::WidgetShortcut,
1837 or to the window itself, Qt::WindowShortcut. For widgets that are not part
1838 of a window (i.e., top-level widgets and their children),
1839 Qt::WindowShortcut shortcuts apply to the scene.
1841 If the same key \a sequence has been grabbed by several widgets,
1842 when the key \a sequence occurs a QEvent::Shortcut event is sent
1843 to all the widgets to which it applies in a non-deterministic
1844 order, but with the ``ambiguous'' flag set to true.
1846 \warning You should not normally need to use this function;
1847 instead create \l{QAction}s with the shortcut key sequences you
1848 require (if you also want equivalent menu options and toolbar
1849 buttons), or create \l{QShortcut}s if you just need key sequences.
1850 Both QAction and QShortcut handle all the event filtering for you,
1851 and provide signals which are triggered when the user triggers the
1852 key sequence, so are much easier to use than this low-level
1855 \sa releaseShortcut() setShortcutEnabled() QWidget::grabShortcut()
1857 int QGraphicsWidget::grabShortcut(const QKeySequence &sequence, Qt::ShortcutContext context)
1860 if (sequence.isEmpty())
1862 // ### setAttribute(Qt::WA_GrabbedShortcut);
1863 return qApp->d_func()->shortcutMap.addShortcut(this, sequence, context);
1869 Removes the shortcut with the given \a id from Qt's shortcut
1870 system. The widget will no longer receive QEvent::Shortcut events
1871 for the shortcut's key sequence (unless it has other shortcuts
1872 with the same key sequence).
1874 \warning You should not normally need to use this function since
1875 Qt's shortcut system removes shortcuts automatically when their
1876 parent widget is destroyed. It is best to use QAction or
1877 QShortcut to handle shortcuts, since they are easier to use than
1878 this low-level function. Note also that this is an expensive
1881 \sa grabShortcut() setShortcutEnabled() , QWidget::releaseShortcut()
1883 void QGraphicsWidget::releaseShortcut(int id)
1887 qApp->d_func()->shortcutMap.removeShortcut(id, this, 0);
1893 If \a enabled is true, the shortcut with the given \a id is
1894 enabled; otherwise the shortcut is disabled.
1896 \warning You should not normally need to use this function since
1897 Qt's shortcut system enables/disables shortcuts automatically as
1898 widgets become hidden/visible and gain or lose focus. It is best
1899 to use QAction or QShortcut to handle shortcuts, since they are
1900 easier to use than this low-level function.
1902 \sa grabShortcut() releaseShortcut(), QWidget::setShortcutEnabled()
1904 void QGraphicsWidget::setShortcutEnabled(int id, bool enabled)
1908 qApp->d_func()->shortcutMap.setShortcutEnabled(enabled, id, this, 0);
1914 If \a enabled is true, auto repeat of the shortcut with the
1915 given \a id is enabled; otherwise it is disabled.
1917 \sa grabShortcut() releaseShortcut() QWidget::setShortcutAutoRepeat()
1919 void QGraphicsWidget::setShortcutAutoRepeat(int id, bool enabled)
1923 qApp->d_func()->shortcutMap.setShortcutAutoRepeat(enabled, id, this, 0);
1927 #ifndef QT_NO_ACTION
1931 Appends the action \a action to this widget's list of actions.
1933 All QGraphicsWidgets have a list of \l{QAction}s, however they can be
1934 represented graphically in many different ways. The default use of the
1935 QAction list (as returned by actions()) is to create a context QMenu.
1937 A QGraphicsWidget should only have one of each action and adding an action
1938 it already has will not cause the same action to be in the widget twice.
1940 \sa removeAction(), insertAction(), actions(), QWidget::addAction()
1942 void QGraphicsWidget::addAction(QAction *action)
1944 insertAction(0, action);
1950 Appends the actions \a actions to this widget's list of actions.
1952 \sa removeAction(), QMenu, addAction(), QWidget::addActions()
1954 void QGraphicsWidget::addActions(QList<QAction *> actions)
1956 for (int i = 0; i < actions.count(); ++i)
1957 insertAction(0, actions.at(i));
1963 Inserts the action \a action to this widget's list of actions,
1964 before the action \a before. It appends the action if \a before is 0 or
1965 \a before is not a valid action for this widget.
1967 A QGraphicsWidget should only have one of each action.
1969 \sa removeAction(), addAction(), QMenu, actions(),
1970 QWidget::insertActions()
1972 void QGraphicsWidget::insertAction(QAction *before, QAction *action)
1975 qWarning("QWidget::insertAction: Attempt to insert null action");
1979 Q_D(QGraphicsWidget);
1980 int index = d->actions.indexOf(action);
1982 d->actions.removeAt(index);
1984 int pos = d->actions.indexOf(before);
1987 pos = d->actions.size();
1989 d->actions.insert(pos, action);
1992 QActionPrivate *apriv = action->d_func();
1993 apriv->graphicsWidgets.append(this);
1996 QActionEvent e(QEvent::ActionAdded, action, before);
1997 QApplication::sendEvent(this, &e);
2003 Inserts the actions \a actions to this widget's list of actions,
2004 before the action \a before. It appends the action if \a before is 0 or
2005 \a before is not a valid action for this widget.
2007 A QGraphicsWidget can have at most one of each action.
2009 \sa removeAction(), QMenu, insertAction(), QWidget::insertActions()
2011 void QGraphicsWidget::insertActions(QAction *before, QList<QAction *> actions)
2013 for (int i = 0; i < actions.count(); ++i)
2014 insertAction(before, actions.at(i));
2020 Removes the action \a action from this widget's list of actions.
2022 \sa insertAction(), actions(), insertAction(), QWidget::removeAction()
2024 void QGraphicsWidget::removeAction(QAction *action)
2029 Q_D(QGraphicsWidget);
2031 QActionPrivate *apriv = action->d_func();
2032 apriv->graphicsWidgets.removeAll(this);
2034 if (d->actions.removeAll(action)) {
2035 QActionEvent e(QEvent::ActionRemoved, action);
2036 QApplication::sendEvent(this, &e);
2043 Returns the (possibly empty) list of this widget's actions.
2045 \sa insertAction(), removeAction(), QWidget::actions(),
2046 QAction::associatedWidgets(), QAction::associatedGraphicsWidgets()
2048 QList<QAction *> QGraphicsWidget::actions() const
2050 Q_D(const QGraphicsWidget);
2056 Moves the \a second widget around the ring of focus widgets so that
2057 keyboard focus moves from the \a first widget to the \a second widget when
2058 the Tab key is pressed.
2060 Note that since the tab order of the \a second widget is changed, you
2061 should order a chain like this:
2063 \snippet doc/src/snippets/code/src_gui_graphicsview_qgraphicswidget.cpp 1
2067 \snippet doc/src/snippets/code/src_gui_graphicsview_qgraphicswidget.cpp 2
2069 If \a first is 0, this indicates that \a second should be the first widget
2070 to receive input focus should the scene gain Tab focus (i.e., the user
2071 hits Tab so that focus passes into the scene). If \a second is 0, this
2072 indicates that \a first should be the first widget to gain focus if the
2073 scene gained BackTab focus.
2075 By default, tab order is defined implicitly using widget creation order.
2077 \sa focusPolicy, {Keyboard Focus}
2079 void QGraphicsWidget::setTabOrder(QGraphicsWidget *first, QGraphicsWidget *second)
2081 if (!first && !second) {
2082 qWarning("QGraphicsWidget::setTabOrder(0, 0) is undefined");
2085 if ((first && second) && first->scene() != second->scene()) {
2086 qWarning("QGraphicsWidget::setTabOrder: scenes %p and %p are different",
2087 first->scene(), second->scene());
2090 QGraphicsScene *scene = first ? first->scene() : second->scene();
2091 if (!scene && (!first || !second)) {
2092 qWarning("QGraphicsWidget::setTabOrder: assigning tab order from/to the"
2093 " scene requires the item to be in a scene.");
2097 // If either first or second are 0, the scene's tabFocusFirst is updated
2098 // to point to the first item in the scene's focus chain. Then first or
2099 // second are set to point to tabFocusFirst.
2100 QGraphicsScenePrivate *sceneD = scene->d_func();
2102 sceneD->tabFocusFirst = second;
2106 sceneD->tabFocusFirst = first->d_func()->focusNext;
2110 // Both first and second are != 0.
2111 QGraphicsWidget *firstFocusNext = first->d_func()->focusNext;
2112 if (firstFocusNext == second) {
2117 // Update the focus chain.
2118 QGraphicsWidget *secondFocusPrev = second->d_func()->focusPrev;
2119 QGraphicsWidget *secondFocusNext = second->d_func()->focusNext;
2120 firstFocusNext->d_func()->focusPrev = second;
2121 first->d_func()->focusNext = second;
2122 second->d_func()->focusNext = firstFocusNext;
2123 second->d_func()->focusPrev = first;
2124 secondFocusPrev->d_func()->focusNext = secondFocusNext;
2125 secondFocusNext->d_func()->focusPrev = secondFocusPrev;
2127 Q_ASSERT(first->d_func()->focusNext->d_func()->focusPrev == first);
2128 Q_ASSERT(first->d_func()->focusPrev->d_func()->focusNext == first);
2130 Q_ASSERT(second->d_func()->focusNext->d_func()->focusPrev == second);
2131 Q_ASSERT(second->d_func()->focusPrev->d_func()->focusNext == second);
2136 If \a on is true, this function enables \a attribute; otherwise
2137 \a attribute is disabled.
2139 See the class documentation for QGraphicsWidget for a complete list of
2140 which attributes are supported, and what they are for.
2142 \sa testAttribute(), QWidget::setAttribute()
2144 void QGraphicsWidget::setAttribute(Qt::WidgetAttribute attribute, bool on)
2146 Q_D(QGraphicsWidget);
2147 // ### most flags require some immediate action
2148 // ### we might want to qWarn use of unsupported attributes
2149 // ### we might want to not use Qt::WidgetAttribute, but roll our own instead
2150 d->setAttribute(attribute, on);
2154 Returns true if \a attribute is enabled for this widget; otherwise,
2159 bool QGraphicsWidget::testAttribute(Qt::WidgetAttribute attribute) const
2161 Q_D(const QGraphicsWidget);
2162 return d->testAttribute(attribute);
2168 int QGraphicsWidget::type() const
2176 void QGraphicsWidget::paint(QPainter *painter, const QStyleOptionGraphicsItem *option, QWidget *widget)
2184 This virtual function is called by QGraphicsScene to draw the window frame
2185 for windows using \a painter, \a option, and \a widget, in local
2186 coordinates. The base implementation uses the current style to render the
2187 frame and title bar.
2189 You can reimplement this function in a subclass of QGraphicsWidget to
2190 provide custom rendering of the widget's window frame.
2192 \sa QGraphicsItem::paint()
2194 void QGraphicsWidget::paintWindowFrame(QPainter *painter, const QStyleOptionGraphicsItem *option,
2197 const bool fillBackground = !testAttribute(Qt::WA_OpaquePaintEvent)
2198 && !testAttribute(Qt::WA_NoSystemBackground);
2199 QGraphicsProxyWidget *proxy = qobject_cast<QGraphicsProxyWidget *>(this);
2200 const bool embeddedWidgetFillsOwnBackground = proxy && proxy->widget();
2202 if (rect().contains(option->exposedRect)) {
2203 if (fillBackground && !embeddedWidgetFillsOwnBackground)
2204 painter->fillRect(option->exposedRect, palette().window());
2208 Q_D(QGraphicsWidget);
2210 QRect windowFrameRect = QRect(QPoint(), windowFrameGeometry().size().toSize());
2211 QStyleOptionTitleBar bar;
2212 bar.QStyleOption::operator=(*option);
2213 d->initStyleOptionTitleBar(&bar); // this clear flags in bar.state
2214 d->ensureWindowData();
2215 if (d->windowData->buttonMouseOver)
2216 bar.state |= QStyle::State_MouseOver;
2218 bar.state &= ~QStyle::State_MouseOver;
2219 if (d->windowData->buttonSunken)
2220 bar.state |= QStyle::State_Sunken;
2222 bar.state &= ~QStyle::State_Sunken;
2224 bar.rect = windowFrameRect;
2226 // translate painter to make the style happy
2227 const QPointF styleOrigin = this->windowFrameRect().topLeft();
2228 painter->translate(styleOrigin);
2231 const QSize pixmapSize = windowFrameRect.size();
2232 if (pixmapSize.width() <= 0 || pixmapSize.height() <= 0)
2234 QPainter *realPainter = painter;
2235 QPixmap pm(pixmapSize);
2236 painter = new QPainter(&pm);
2240 QStyleHintReturnMask mask;
2241 bool setMask = style()->styleHint(QStyle::SH_WindowFrame_Mask, &bar, widget, &mask) && !mask.region.isEmpty();
2242 bool hasBorder = !style()->styleHint(QStyle::SH_TitleBar_NoBorder, &bar, widget);
2243 int frameWidth = style()->pixelMetric(QStyle::PM_MDIFrameWidth, &bar, widget);
2246 painter->setClipRegion(mask.region, Qt::IntersectClip);
2248 if (fillBackground) {
2249 if (embeddedWidgetFillsOwnBackground) {
2250 // Don't fill the background twice.
2251 QPainterPath windowFrameBackground;
2252 windowFrameBackground.addRect(windowFrameRect);
2253 // Adjust with 0.5 to avoid border artifacts between
2254 // widget background and frame background.
2255 windowFrameBackground.addRect(rect().translated(-styleOrigin).adjusted(0.5, 0.5, -0.5, -0.5));
2256 painter->fillPath(windowFrameBackground, palette().window());
2258 painter->fillRect(windowFrameRect, palette().window());
2261 painter->setRenderHint(QPainter::NonCosmeticDefaultPen);
2264 int height = (int)d->titleBarHeight(bar);
2265 bar.rect.setHeight(height);
2266 if (hasBorder) // Frame is painted by PE_FrameWindow
2267 bar.rect.adjust(frameWidth, frameWidth, -frameWidth, 0);
2270 painter->setFont(QApplication::font("QWorkspaceTitleBar"));
2271 style()->drawComplexControl(QStyle::CC_TitleBar, &bar, painter, widget);
2275 // Draw window frame
2276 QStyleOptionFrame frameOptions;
2277 frameOptions.QStyleOption::operator=(*option);
2278 initStyleOption(&frameOptions);
2280 painter->setClipRect(windowFrameRect.adjusted(0, +height, 0, 0), Qt::IntersectClip);
2282 frameOptions.state |= QStyle::State_HasFocus;
2284 frameOptions.state &= ~QStyle::State_HasFocus;
2286 bool isActive = isActiveWindow();
2288 frameOptions.state |= QStyle::State_Active;
2290 frameOptions.state &= ~QStyle::State_Active;
2293 frameOptions.palette.setCurrentColorGroup(isActive ? QPalette::Active : QPalette::Normal);
2294 frameOptions.rect = windowFrameRect;
2295 frameOptions.lineWidth = style()->pixelMetric(QStyle::PM_MdiSubWindowFrameWidth, 0, widget);
2296 frameOptions.midLineWidth = 1;
2297 style()->drawPrimitive(QStyle::PE_FrameWindow, &frameOptions, painter, widget);
2300 realPainter->drawPixmap(QPoint(), pm);
2308 QRectF QGraphicsWidget::boundingRect() const
2310 return windowFrameRect();
2316 QPainterPath QGraphicsWidget::shape() const
2319 path.addRect(rect());
2324 Call this function to close the widget.
2326 Returns true if the widget was closed; otherwise returns false.
2327 This slot will first send a QCloseEvent to the widget, which may or may
2328 not accept the event. If the event was ignored, nothing happens. If the
2329 event was accepted, it will hide() the widget.
2331 If the widget has the Qt::WA_DeleteOnClose attribute set it will be
2334 bool QGraphicsWidget::close()
2336 QCloseEvent closeEvent;
2337 QApplication::sendEvent(this, &closeEvent);
2338 if (!closeEvent.isAccepted()) {
2345 if (testAttribute(Qt::WA_DeleteOnClose)) {
2351 #ifdef Q_NO_USING_KEYWORD
2353 \fn const QObjectList &QGraphicsWidget::children() const
2356 This function returns the same value as QObject::children(). It's
2357 provided to differentiate between the obsolete member
2358 QGraphicsItem::children() and QObject::children(). QGraphicsItem now
2359 provides childItems() instead.
2364 void QGraphicsWidget::dumpFocusChain()
2366 qDebug() << "=========== Dumping focus chain ==============";
2368 QGraphicsWidget *next = this;
2369 QSet<QGraphicsWidget*> visited;
2372 qWarning("Found a focus chain that is not circular, (next == 0)");
2375 qDebug() << i++ << QString::number(uint(next), 16) << next->className() << next->data(0) << QString::fromAscii("focusItem:%1").arg(next->hasFocus() ? '1' : '0') << QLatin1String("next:") << next->d_func()->focusNext->data(0) << QLatin1String("prev:") << next->d_func()->focusPrev->data(0);
2376 if (visited.contains(next)) {
2377 qWarning("Already visited this node. However, I expected to dump until I found myself.");
2381 next = next->d_func()->focusNext;
2382 } while (next != this);
2388 #endif //QT_NO_GRAPHICSVIEW