From b206fba8b1f6c8b03c7d23bccdaf0888727ce6b6 Mon Sep 17 00:00:00 2001 From: Jerome Pasion Date: Thu, 18 Oct 2012 15:15:04 +0200 Subject: [PATCH] Doc: Adding Event System documentation. Previously in qtdoc repository. Change-Id: I9f5cc876f2b49e86520097c0d8efe7e21eabc04e Reviewed-by: Martin Smith --- .../doc/snippets/eventfilters/filterobject.cpp | 74 +++++++ .../doc/snippets/eventfilters/filterobject.h | 59 ++++++ src/corelib/doc/snippets/eventfilters/main.cpp | 54 +++++ src/corelib/doc/snippets/events/events.cpp | 97 +++++++++ src/corelib/doc/src/eventsandfilters.qdoc | 220 +++++++++++++++++++++ 5 files changed, 504 insertions(+) create mode 100644 src/corelib/doc/snippets/eventfilters/filterobject.cpp create mode 100644 src/corelib/doc/snippets/eventfilters/filterobject.h create mode 100644 src/corelib/doc/snippets/eventfilters/main.cpp create mode 100644 src/corelib/doc/snippets/events/events.cpp create mode 100644 src/corelib/doc/src/eventsandfilters.qdoc diff --git a/src/corelib/doc/snippets/eventfilters/filterobject.cpp b/src/corelib/doc/snippets/eventfilters/filterobject.cpp new file mode 100644 index 0000000..81591f4 --- /dev/null +++ b/src/corelib/doc/snippets/eventfilters/filterobject.cpp @@ -0,0 +1,74 @@ +/**************************************************************************** +** +** Copyright (C) 2012 Digia Plc and/or its subsidiary(-ies). +** Contact: http://www.qt-project.org/legal +** +** This file is part of the documentation of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:BSD$ +** You may use this file under the terms of the BSD license as follows: +** +** "Redistribution and use in source and binary forms, with or without +** modification, are permitted provided that the following conditions are +** met: +** * Redistributions of source code must retain the above copyright +** notice, this list of conditions and the following disclaimer. +** * Redistributions in binary form must reproduce the above copyright +** notice, this list of conditions and the following disclaimer in +** the documentation and/or other materials provided with the +** distribution. +** * Neither the name of Digia Plc and its Subsidiary(-ies) nor the names +** of its contributors may be used to endorse or promote products derived +** from this software without specific prior written permission. +** +** +** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE." +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#include + +#include "filterobject.h" + +FilterObject::FilterObject(QObject *parent) + : QObject(parent), target(0) +{ +} + +//! [0] +bool FilterObject::eventFilter(QObject *object, QEvent *event) +{ + if (object == target && event->type() == QEvent::KeyPress) { + QKeyEvent *keyEvent = static_cast(event); + if (keyEvent->key() == Qt::Key_Tab) { + // Special tab handling + return true; + } else + return false; + } + return false; +} +//! [0] + +void FilterObject::setFilteredObject(QObject *object) +{ + if (target) + target->removeEventFilter(this); + + target = object; + + if (target) + target->installEventFilter(this); +} diff --git a/src/corelib/doc/snippets/eventfilters/filterobject.h b/src/corelib/doc/snippets/eventfilters/filterobject.h new file mode 100644 index 0000000..8c9d2e7 --- /dev/null +++ b/src/corelib/doc/snippets/eventfilters/filterobject.h @@ -0,0 +1,59 @@ +/**************************************************************************** +** +** Copyright (C) 2012 Digia Plc and/or its subsidiary(-ies). +** Contact: http://www.qt-project.org/legal +** +** This file is part of the documentation of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:BSD$ +** You may use this file under the terms of the BSD license as follows: +** +** "Redistribution and use in source and binary forms, with or without +** modification, are permitted provided that the following conditions are +** met: +** * Redistributions of source code must retain the above copyright +** notice, this list of conditions and the following disclaimer. +** * Redistributions in binary form must reproduce the above copyright +** notice, this list of conditions and the following disclaimer in +** the documentation and/or other materials provided with the +** distribution. +** * Neither the name of Digia Plc and its Subsidiary(-ies) nor the names +** of its contributors may be used to endorse or promote products derived +** from this software without specific prior written permission. +** +** +** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE." +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#ifndef FILTEROBJECT_H +#define FILTEROBJECT_H + +#include + +class FilterObject : public QObject +{ + Q_OBJECT + +public: + FilterObject(QObject *parent = 0); + bool eventFilter(QObject *object, QEvent *event); + void setFilteredObject(QObject *object); + +private: + QObject *target; +}; + +#endif diff --git a/src/corelib/doc/snippets/eventfilters/main.cpp b/src/corelib/doc/snippets/eventfilters/main.cpp new file mode 100644 index 0000000..7f6bde4 --- /dev/null +++ b/src/corelib/doc/snippets/eventfilters/main.cpp @@ -0,0 +1,54 @@ +/**************************************************************************** +** +** Copyright (C) 2012 Digia Plc and/or its subsidiary(-ies). +** Contact: http://www.qt-project.org/legal +** +** This file is part of the documentation of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:BSD$ +** You may use this file under the terms of the BSD license as follows: +** +** "Redistribution and use in source and binary forms, with or without +** modification, are permitted provided that the following conditions are +** met: +** * Redistributions of source code must retain the above copyright +** notice, this list of conditions and the following disclaimer. +** * Redistributions in binary form must reproduce the above copyright +** notice, this list of conditions and the following disclaimer in +** the documentation and/or other materials provided with the +** distribution. +** * Neither the name of Digia Plc and its Subsidiary(-ies) nor the names +** of its contributors may be used to endorse or promote products derived +** from this software without specific prior written permission. +** +** +** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE." +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#include +#include + +#include "filterobject.h" + +int main(int argc, char *argv[]) +{ + QApplication app(argc, argv); + QTextEdit editor; + FilterObject filter; + filter.setFilteredObject(&editor); + editor.show(); + return app.exec(); +} diff --git a/src/corelib/doc/snippets/events/events.cpp b/src/corelib/doc/snippets/events/events.cpp new file mode 100644 index 0000000..a3a95d6 --- /dev/null +++ b/src/corelib/doc/snippets/events/events.cpp @@ -0,0 +1,97 @@ +/**************************************************************************** +** +** Copyright (C) 2012 Digia Plc and/or its subsidiary(-ies). +** Contact: http://www.qt-project.org/legal +** +** This file is part of the documentation of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:BSD$ +** You may use this file under the terms of the BSD license as follows: +** +** "Redistribution and use in source and binary forms, with or without +** modification, are permitted provided that the following conditions are +** met: +** * Redistributions of source code must retain the above copyright +** notice, this list of conditions and the following disclaimer. +** * Redistributions in binary form must reproduce the above copyright +** notice, this list of conditions and the following disclaimer in +** the documentation and/or other materials provided with the +** distribution. +** * Neither the name of Digia Plc and its Subsidiary(-ies) nor the names +** of its contributors may be used to endorse or promote products derived +** from this software without specific prior written permission. +** +** +** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE." +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#include +#include + +class MyCheckBox : public QCheckBox +{ +public: + void mousePressEvent(QMouseEvent *event); +}; + +//! [0] +void MyCheckBox::mousePressEvent(QMouseEvent *event) +{ + if (event->button() == Qt::LeftButton) { + // handle left mouse button here + } else { + // pass on other buttons to base class + QCheckBox::mousePressEvent(event); + } +} +//! [0] + +class MyWidget : public QWidget +{ +public: + bool event(QEvent *event); +}; + +static const int MyCustomEventType = 1099; + +class MyCustomEvent : public QEvent +{ +public: + MyCustomEvent() : QEvent((QEvent::Type)MyCustomEventType) {} +}; + +//! [1] +bool MyWidget::event(QEvent *event) +{ + if (event->type() == QEvent::KeyPress) { + QKeyEvent *ke = static_cast(event); + if (ke->key() == Qt::Key_Tab) { + // special tab handling here + return true; + } + } else if (event->type() == MyCustomEventType) { + MyCustomEvent *myEvent = static_cast(event); + // custom event handling here + return true; + } + + return QWidget::event(event); +} +//! [1] + +int main() +{ +} diff --git a/src/corelib/doc/src/eventsandfilters.qdoc b/src/corelib/doc/src/eventsandfilters.qdoc new file mode 100644 index 0000000..5fe4445 --- /dev/null +++ b/src/corelib/doc/src/eventsandfilters.qdoc @@ -0,0 +1,220 @@ +/**************************************************************************** +** +** Copyright (C) 2012 Digia Plc and/or its subsidiary(-ies). +** Contact: http://www.qt-project.org/legal +** +** This file is part of the documentation of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:FDL$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and Digia. For licensing terms and +** conditions see http://qt.digia.com/licensing. For further information +** use the contact form at http://qt.digia.com/contact-us. +** +** GNU Free Documentation License Usage +** Alternatively, this file may be used under the terms of the GNU Free +** Documentation License version 1.3 as published by the Free Software +** Foundation and appearing in the file included in the packaging of +** this file. Please review the following information to ensure +** the GNU Free Documentation License version 1.3 requirements +** will be met: http://www.gnu.org/copyleft/fdl.html. +** $QT_END_LICENSE$ +** +****************************************************************************/ + +/*! + \group events + \title Event Classes + \ingroup groups + + \brief Classes used to create and handle events. + + These classes are used to create and handle events. + + For more information see the \link object.html Object model\endlink + and \link signalsandslots.html Signals and Slots\endlink. +*/ + +/*! + \page eventsandfilters.html + \title The Event System + \ingroup qt-basic-concepts + \brief A guide to event handling in Qt. + + \ingroup frameworks-technologies + + In Qt, events are objects, derived from the abstract QEvent class, + that represent things that have happened either within an application + or as a result of outside activity that the application needs to know + about. Events can be received and handled by any instance of a + QObject subclass, but they are especially relevant to widgets. This + document describes how events are delivered and handled in a typical + application. + + \section1 How Events are Delivered + + When an event occurs, Qt creates an event object to represent it by + constructing an instance of the appropriate QEvent subclass, and + delivers it to a particular instance of QObject (or one of its + subclasses) by calling its \l{QObject::}{event()} function. + + This function does not handle the event itself; based on the type + of event delivered, it calls an event handler for that specific + type of event, and sends a response based on whether the event + was accepted or ignored. + + \omit + Event delivery means that an + event has occurred, the QEvent indicates precisely what, and the + QObject needs to respond. Most events are specific to QWidget and its + subclasses, but there are important events that aren't related to + graphics (e.g., \l{QTimer}{timer events}). + \endomit + + Some events, such as QMouseEvent and QKeyEvent, come from the + window system; some, such as QTimerEvent, come from other sources; + some come from the application itself. + + \section1 Event Types + + Most events types have special classes, notably QResizeEvent, + QPaintEvent, QMouseEvent, QKeyEvent, and QCloseEvent. Each class + subclasses QEvent and adds event-specific functions. For example, + QResizeEvent adds \l{QResizeEvent::}{size()} and + \l{QResizeEvent::}{oldSize()} to enable widgets to discover how + their dimensions have been changed. + + Some classes support more than one actual event type. QMouseEvent + supports mouse button presses, double-clicks, moves, and other + related operations. + + Each event has an associated type, defined in QEvent::Type, and this + can be used as a convenient source of run-time type information to + quickly determine which subclass a given event object was constructed + from. + + Since programs need to react in varied and complex ways, Qt's + event delivery mechanisms are flexible. The documentation for + QCoreApplication::notify() concisely tells the whole story; the + \e{Qt Quarterly} article + \l{http://doc.qt.nokia.com/qq/qq11-events.html}{Another Look at Events} + rehashes it less concisely. Here we will explain enough for 95% + of applications. + + \section1 Event Handlers + + The normal way for an event to be delivered is by calling a virtual + function. For example, QPaintEvent is delivered by calling + QWidget::paintEvent(). This virtual function is responsible for + reacting appropriately, normally by repainting the widget. If you + do not perform all the necessary work in your implementation of the + virtual function, you may need to call the base class's implementation. + + For example, the following code handles left mouse button clicks on + a custom checkbox widget while passing all other button clicks to the + base QCheckBox class: + + \snippet events/events.cpp 0 + + If you want to replace the base class's function, you must + implement everything yourself. However, if you only want to extend + the base class's functionality, then you implement what you want and + call the base class to obtain the default behavior for any cases you + do not want to handle. + + Occasionally, there isn't such an event-specific function, or the + event-specific function isn't sufficient. The most common example + involves Tab key presses. Normally, QWidget intercepts these to + move the keyboard focus, but a few widgets need the Tab key for + themselves. + + These objects can reimplement QObject::event(), the general event + handler, and either do their event handling before or after the usual + handling, or they can replace the function completely. A very unusual + widget that both interprets Tab and has an application-specific + custom event might contain the following \l{QObject::event()}{event()} + function: + + \snippet events/events.cpp 1 + + Note that QWidget::event() is still called for all of the cases not + handled, and that the return value indicates whether an event was + dealt with; a \c true value prevents the event from being sent on + to other objects. + + \section1 Event Filters + + Sometimes an object needs to look at, and possibly intercept, the + events that are delivered to another object. For example, dialogs + commonly want to filter key presses for some widgets; for example, + to modify Return-key handling. + + The QObject::installEventFilter() function enables this by setting + up an \e{event filter}, causing a nominated filter object to receive + the events for a target object in its QObject::eventFilter() + function. An event filter gets to process events before the target + object does, allowing it to inspect and discard the events as + required. An existing event filter can be removed using the + QObject::removeEventFilter() function. + + When the filter object's \l{QObject::}{eventFilter()} implementation + is called, it can accept or reject the event, and allow or deny + further processing of the event. If all the event filters allow + further processing of an event (by each returning \c false), the event + is sent to the target object itself. If one of them stops processing + (by returning \c true), the target and any later event filters do not + get to see the event at all. + + \snippet eventfilters/filterobject.cpp 0 + + The above code shows another way to intercept Tab key press + events sent to a particular target widget. In this case, the filter + handles the relevant events and returns \c true to stop them from + being processed any further. All other events are ignored, and the + filter returns \c false to allow them to be sent on to the target + widget, via any other event filters that are installed on it. + + It is also possible to filter \e all events for the entire application, + by installing an event filter on the QApplication or QCoreApplication + object. Such global event filters are called before the object-specific + filters. This is very powerful, but it also slows down event delivery + of every single event in the entire application; the other techniques + discussed should generally be used instead. + + \section1 Sending Events + + Many applications want to create and send their own events. You can + send events in exactly the same ways as Qt's own event loop by + constructing suitable event objects and sending them with + QCoreApplication::sendEvent() and QCoreApplication::postEvent(). + + \l{QCoreApplication::}{sendEvent()} processes the event immediately. + When it returns, the event filters and/or the object itself have + already processed the event. For many event classes there is a function + called isAccepted() that tells you whether the event was accepted + or rejected by the last handler that was called. + + \l{QCoreApplication::}{postEvent()} posts the event on a queue for + later dispatch. The next time Qt's main event loop runs, it dispatches + all posted events, with some optimization. For example, if there are + several resize events, they are compressed into one. The same + applies to paint events: QWidget::update() calls + \l{QCoreApplication::}{postEvent()}, which eliminates flickering and + increases speed by avoiding multiple repaints. + + \l{QCoreApplication::}{postEvent()} is also used during object + initialization, since the posted event will typically be dispatched + very soon after the initialization of the object is complete. + When implementing a widget, it is important to realise that events + can be delivered very early in its lifetime so, in its constructor, + be sure to initialize member variables early on, before there's any + chance that it might receive an event. + + To create events of a custom type, you need to define an event + number, which must be greater than QEvent::User, and you may need to + subclass QEvent in order to pass specific information about your + custom event. See the QEvent documentation for further details. +*/ -- 2.7.4