📄 qwidget.cpp
字号:
setCursor() font(), setFont(), palette(), setPalette(), backgroundRole(), setBackgroundRole(), fontMetrics(), fontInfo(). \row \i Keyboard focus functions \i setFocusPolicy(), focusPolicy(), hasFocus(), setFocus(), clearFocus(), setTabOrder(), setFocusProxy(). \row \i Mouse and keyboard grabbing \i grabMouse(), releaseMouse(), grabKeyboard(), releaseKeyboard(), mouseGrabber(), keyboardGrabber(). \row \i Event handlers \i event(), mousePressEvent(), mouseReleaseEvent(), mouseDoubleClickEvent(), mouseMoveEvent(), keyPressEvent(), keyReleaseEvent(), focusInEvent(), focusOutEvent(), wheelEvent(), enterEvent(), leaveEvent(), paintEvent(), moveEvent(), resizeEvent(), closeEvent(), dragEnterEvent(), dragMoveEvent(), dragLeaveEvent(), dropEvent(), childEvent(), showEvent(), hideEvent(), customEvent(). changeEvent(), \row \i System functions \i parentWidget(), window(), setParent(), winId(), find(), metric(). \row \i What's this help \i setWhatsThis() \row \i Focus functions \i focusNextChild(), focusPreviousChild() \endtable Every widget's constructor accepts one or two standard arguments: \list 1 \i \c{QWidget *parent = 0} is the parent of the new widget. If it is 0 (the default), the new widget will be a window. If not, it will be a child of \e parent, and be constrained by \e parent's geometry (unless you specify Qt::Window as window flag). \i \c{Qt::WFlags f = 0} (where available) sets the window flags; the default is suitable for almost all widgets, but to get, for example, a window without a window system frame, you must use special flags. \endlist The \l widgets/calculator example program is good example of a simple widget. It contains event handlers (as all widgets must), routines that are specific to it (as all useful widgets do), and has children and connections. Everything it does is done in response to an event: this is by far the most common way to design GUI applications. You will need to supply the content for your widgets yourself, but here is a brief run-down of the events, starting with the most common ones: \list \i paintEvent() - called whenever the widget needs to be repainted. Every widget which displays output must implement it. Painting using a QPainter can only take place in a paintEvent() or a function called by a paintEvent(). \i resizeEvent() - called when the widget has been resized. \i mousePressEvent() - called when a mouse button is pressed. There are six mouse-related events, but the mouse press and mouse release events are by far the most important. A widget receives mouse press events when the mouse is inside it, or when it has grabbed the mouse using grabMouse(). \i mouseReleaseEvent() - called when a mouse button is released. A widget receives mouse release events when it has received the corresponding mouse press event. This means that if the user presses the mouse inside \e your widget, then drags the mouse to somewhere else, then releases, \e your widget receives the release event. There is one exception: if a popup menu appears while the mouse button is held down, this popup immediately steals the mouse events. \i mouseDoubleClickEvent() - not quite as obvious as it might seem. If the user double-clicks, the widget receives a mouse press event (perhaps a mouse move event or two if they don't hold the mouse quite steady), a mouse release event and finally this event. It is \e{not possible} to distinguish a click from a double click until you've seen whether the second click arrives. (This is one reason why most GUI books recommend that double clicks be an extension of single clicks, rather than trigger a different action.) \endlist If your widget only contains child widgets, you probably do not need to implement any event handlers. If you want to detect a mouse click in a child widget call the child's underMouse() function inside the parent widget's mousePressEvent(). Widgets that accept keyboard input need to reimplement a few more event handlers: \list \i keyPressEvent() - called whenever a key is pressed, and again when a key has been held down long enough for it to auto-repeat. Note that the Tab and Shift+Tab keys are only passed to the widget if they are not used by the focus-change mechanisms. To force those keys to be processed by your widget, you must reimplement QWidget::event(). \i focusInEvent() - called when the widget gains keyboard focus (assuming you have called setFocusPolicy()). Well written widgets indicate that they own the keyboard focus in a clear but discreet way. \i focusOutEvent() - called when the widget loses keyboard focus. \endlist Some widgets will also need to reimplement some of the less common event handlers: \list \i mouseMoveEvent() - called whenever the mouse moves while a button is held down. This is useful for, for example, dragging. If you call setMouseTracking(true), you get mouse move events even when no buttons are held down. (See also the \link dnd.html drag and drop\endlink information.) \i keyReleaseEvent() - called whenever a key is released, and also while it is held down if the key is auto-repeating. In that case the widget receives a key release event and immediately a key press event for every repeat. Note that the Tab and Shift+Tab keys are only passed to the widget if they are not used by the focus-change mechanisms. To force those keys to be processed by your widget, you must reimplement QWidget::event(). \i wheelEvent() -- called whenever the user turns the mouse wheel while the widget has the focus. \i enterEvent() - called when the mouse enters the widget's screen space. (This excludes screen space owned by any children of the widget.) \i leaveEvent() - called when the mouse leaves the widget's screen space. Note that if the mouse enters a child widget it will not cause a leaveEvent. \i moveEvent() - called when the widget has been moved relative to its parent. \i closeEvent() - called when the user closes the widget (or when close() is called). \endlist There are also some rather obscure events. They are listed in \c qevent.h and you need to reimplement event() to handle them. The default implementation of event() handles Tab and Shift+Tab (to move the keyboard focus), and passes on most other events to one of the more specialized handlers above. When implementing a widget, there are a few more things to consider. \list \i In the constructor, be sure to set up your member variables early on, before there's any chance that you might receive an event. \i It is almost always useful to reimplement sizeHint() and to set the correct size policy with setSizePolicy(), so users of your class can set up layout management more easily. A size policy lets you supply good defaults for the layout management handling, so that other widgets can contain and manage yours easily. sizeHint() indicates a "good" size for the widget. \i If your widget is a window, setWindowTitle() and setWindowIcon() set the title bar and icon respectively. \endlist \section1 Transparency and Double Buffering From Qt 4.0, QWidget automatically double-buffers its painting, so there's no need to write double-buffering code in paintEvent() to avoid flicker. Additionally, it became possible for widgets to propagate their contents to children, in order to enable transparency effects, by setting the Qt::WA_ContentsPropagated widget attribute - this is now deprecated in Qt 4.1. In Qt 4.1, the contents of parent widgets are propagated by default to each of their children. Custom widgets can be written to take advantage of this feature by only updating irregular regions (to create non-rectangular child widgets), or by using painting with colors that have less than the full alpha component. The following diagram shows how attributes and properties of a custom widget can be fine-tuned to achieve different effects. \image propagation-custom.png In the above diagram, a semi-transparent rectangular child widget with an area removed is constructed and added to a parent widget (a QLabel showing a pixmap) then different properties and widget attributes are set to achieve different effects: \list \o The top-left widget has no additional properties or widget attributes set. This default state suits most custom widgets that use transparency or are irregularly-shaped, and that do not paint over their entire area with an opaque brush. \o The top-right widget has the \l autoFillBackground property set. This property is used with custom widgets that rely on the widget to supply a default background, and do not paint over their entire area with an opaque brush. \o The bottom-left widget has the Qt::WA_OpaquePaintEvent widget attribute set. This indicates that the widget will paint over its entire area with opaque colors. The widget's area will initially be \e{uninitialized} (represented in the diagram by a red diagonal grid pattern that shines through the overpainted area). This is useful for widgets that need to paint their own specialized contents quickly and that do not need a default filled background. \endlist For rapidly updating custom widgets with simple background colors, such as real-time plotting or graphing widgets, it is better to define a suitable background color (using setBackgroundRole() with the QPalette::Window role), set the \l autoFillBackground property, and only implement the necessary drawing functionality in the widget's paintEvent(). For rapidly updating custom widgets that constantly paint over their entire areas with opaque content, such as video streaming widgets, it is better to set the widget's Qt::WA_OpaquePaintEvent, avoiding any unnecessary overhead associated with repainting the widget's background. If a widget has both the Qt::WA_OpaquePaintEvent widget attribute \e{and} the \l autoFillBackground property set, the Qt::WA_OpaquePaintEvent attribute takes precedence. You should choose just one of these depending on your requirements. In Qt 4.1, the contents of parent widgets are also propagated to standard Qt widgets. This can lead to some unexpected results if the parent widget is decorated in a non-standard way, as shown in the diagram below. \image propagation-standard.png The scope for customizing the painting behavior of standard Qt widgets, without resorting to subclassing, is slightly less than that possible for custom widgets. Usually, the desired appearance of a standard widget can be achieved by setting its \l autoFillBackground property. \sa QEvent, QPainter, QGridLayout, QBoxLayout*/QWidgetMapper *QWidgetPrivate::mapper = 0; // app global widget mapper/***************************************************************************** QWidget utility functions *****************************************************************************/static QFont qt_naturalWidgetFont(QWidget* w) { QFont naturalfont = QApplication::font(w); if (w->parentWidget() && (!w->isWindow() || w->testAttribute(Qt::WA_WindowPropagation))) { if (!naturalfont.isCopyOf(QApplication::font())) naturalfont = naturalfont.resolve(w->parentWidget()->font()); else naturalfont = w->parentWidget()->font(); } naturalfont.resolve(0); return naturalfont;}static QPalette qt_naturalWidgetPalette(QWidget* w) { QPalette naturalpalette = QApplication::palette(w); if (w->parentWidget() && (!w->isWindow() || w->testAttribute(Qt::WA_WindowPropagation))) { if (!naturalpalette.isCopyOf(QApplication::palette())) naturalpalette = naturalpalette.resolve(w->parentWidget()->palette()); else naturalpalette = w->parentWidget()->palette(); } naturalpalette.resolve(0); return naturalpalette;}/***************************************************************************** QWidget member functions *****************************************************************************//* Widget state flags: \list \i Qt::WA_WState_Created The widget has a valid winId(). \i Qt::WA_WState_Visible The widget is currently visible. \i Qt::WA_WState_Hidden The widget is hidden, i.e. it won't become visible unless you call show() on it. Qt::WA_WState_Hidden implies !Qt::WA_WState_Visible. \i Qt::WA_WState_CompressKeys Compress keyboard events. \i Qt::WA_WState_BlockUpdates Repaints and updates are disabled. \i Qt::WA_WState_InPaintEvent Currently processing a paint event. \i Qt::WA_WState_Reparented The widget has been reparented. \i Qt::WA_WState_ConfigPending A configuration (resize/move) event is pending. \i Qt::WA_WState_DND The widget supports drag and drop, see setAcceptDrops(). ### depricated \endlist*//*! Constructs a widget which is a child of \a parent, with widget flags set to \a f. If \a parent is 0, the new widget becomes a window. If \a parent is another widget, this widget becomes a child window inside \a parent. The new widget is deleted when its \a parent is deleted. The widget flags argument, \a f, is normally 0, but it can be set to customize the frame of a window (i.e. \a parent must be 0). To customize the frame, use a value composed from the bitwise OR of any of the \l{Qt::WindowFlags}{window flags}. If you add a child widget to an already visible widget you must explicitly show the child to make it visible. Note that the X11 version of Qt may not be able to deliver all combinations of style flags on all systems. This is because on X11, Qt can only ask the window manager, and the window manager can override the application's settings. On Windows, Qt can set whatever flags you want.*/QWidget::QWidget(QWidget *parent, Qt::WFlags f) : QObject(*new QWidgetPrivate, ((parent && (parent->windowType() == Qt::Desktop)) ? 0 : parent)), QPaintDevice(){ d_func()->init((parent && parent->windowType() == Qt::Desktop ? parent : 0), f);}#ifdef QT3_SUPPORT/*! \overload \obsolete */QWidget::QWidget(QWidget *parent, const char *name, Qt::WFlags f) : QObject(*new QWidgetPrivate, ((parent && (parent->windowType() == Qt::Desktop)) ? 0 : parent)), QPaintDevice(){ d_func()->init((parent && parent->windowType() == Qt::Desktop ? parent : 0), f); setObjectName(QString::fromAscii(name));}#endif/*! \internal*/QWidget::QWidget(QWidgetPrivate &dd, QWidget* parent, Qt::WFlags f) : QObject(dd, ((parent && (parent->windowType() == Qt::Desktop)) ? 0 : parent)), QPaintDevice(){ d_func()->init((parent && parent->windowType() == Qt::Desktop ? parent : 0), f);}/*! \internal*/int QWidget::devType() const{ return QInternal::Widget;}void QWidgetPrivate::init(QWidget *desktopWidget, Qt::WFlags f){ Q_Q(QWidget); q->data = &data; if (qApp->type() == QApplication::Tty) qWarning("QWidget: Cannot create a QWidget when no GUI is being used");#ifndef QT_NO_THREAD if (!q->parent()) { Q_ASSERT_X(q->thread() == qApp->thread(), "QWidget", "Widgets must be created in the GUI thread."); }#endif#if defined(Q_WS_X11) if (desktopWidget) { // make sure the widget is created on the same screen as the // programmer specified desktop widget xinfo = desktopWidget->d_func()->xinfo; }#else Q_UNUSED(desktopWidget);#endif data.fstrut_dirty = 1; data.winid = 0;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -