| /**************************************************************************** |
| ** |
| ** Copyright (C) 2016 The Qt Company Ltd. |
| ** Contact: https://www.qt.io/licensing/ |
| ** |
| ** 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 The Qt Company. For licensing terms |
| ** and conditions see https://www.qt.io/terms-conditions. For further |
| ** information use the contact form at https://www.qt.io/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: https://www.gnu.org/licenses/fdl-1.3.html. |
| ** $QT_END_LICENSE$ |
| ** |
| ****************************************************************************/ |
| |
| /*! |
| \example graphicsview/padnavigator |
| \title Pad Navigator Example |
| \ingroup examples-graphicsview |
| \brief Demonstrates how to create animated user interface. |
| |
| The Pad Navigator Example shows how you can use Graphics View together with |
| embedded widgets and Qt's \l{The State Machine Framework}{state machine |
| framework} to create a simple but useful, dynamic, animated user interface. |
| |
| \image padnavigator-example.png |
| |
| The interface consists of a flippable, rotating pad with icons that can be |
| selected using the arrow keys on your keyboard or keypad. Pressing enter |
| will flip the pad around and reveal its back side, which has a form |
| embedded into a QGraphicsProxyWidget. You can interact with the form, and |
| press the enter key to flip back to the front side of the pad at any time. |
| |
| Graphics View provides the QGraphicsScene class for managing and |
| interacting with a large number of custom-made 2D graphical items derived |
| from the QGraphicsItem class, and a QGraphicsView widget for visualizing |
| the items, with support for zooming and rotation. |
| |
| This example consists of a \c RoundRectItem class, a \c FlippablePad class, |
| a \c PadNavigator class, a \c SplashItem class, and a \c main() function. |
| |
| \section1 RoundRectItem Class Definition |
| |
| The \c RoundRectItem class is used by itself to display the icons on the |
| pad, and as a base class for \c FlippablePad, the class for the pad itself. |
| The role of the class is to paint a round rectangle of a specified size and |
| gradient color, and optionally to paint a pixmap icon on top. To support \c |
| FlippablePad it also allows filling its contents with a plain window |
| background color. |
| |
| Let's start by reviewing the \c RoundRectItem class declaration. |
| |
| \snippet graphicsview/padnavigator/roundrectitem.h 0 |
| |
| \c RoundRectItem inherits QGraphicsObject, which makes it easy to control |
| its properties using QPropertyAnimation. Its constructor takes a rectangle |
| to determine its bounds, and a color. |
| |
| Besides implementing the mandatory \l{QGraphicsItem::paint()}{paint()} and |
| \l{QGraphicsItem::boundingRect()}{boundingRect()} pure virtual functions, |
| it also provides the \c pixmap and \c fill properties. |
| |
| The \c pixmap property sets an optional pixmap that is drawn on top of the |
| round rectangle. The \c fill property will, when true, fill the round |
| rectangle contents with a fixed QPalette::Window background color. |
| Otherwise the contents are filled using a gradient based on the color |
| passed to \c RoundRectItem's constructor. |
| |
| \snippet graphicsview/padnavigator/roundrectitem.h 1 |
| |
| The private data members are: |
| |
| \list |
| \li \c pix: The optional pixmap that is drawn on top of the rectangle. |
| \li \c fillRect: Corresponds to the \c fill property. |
| \li \c color: The configurable gradient color fill of the rectangle. |
| \li \c bounds: The bounds of the rectangle. |
| \li \c gradient: A precalculated gradient used to fill the rectangle. |
| \endlist |
| |
| We will now review the \c RoundRectItem implementation. Let's start by |
| looking at its constructor: |
| |
| \snippet graphicsview/padnavigator/roundrectitem.cpp 0 |
| |
| The constructor initializes its member variables and forwards the \c parent |
| argument to QGraphicsObject's constructor. It then constructs the linear |
| gradient that is used in \l{QGraphicsItem::paint()}{paint()} to draw the |
| round rectangle's gradient background. The linear gradient's starting point |
| is at the top-left corner of the bounds, and the end is at the bottom-left |
| corner. The start color is identical to the color passed as an argument, |
| and a slightly darker color is chosen for the final stop. |
| |
| We store this gradient as a member variable to avoid having to recreate the |
| gradient every time the item is repainted. |
| |
| Finally we set the cache mode |
| \l{QGraphicsItem::ItemCoordinateCache}{ItemCoordinateCache}. This mode |
| causes the item's rendering to be cached into an off-screen pixmap that |
| remains persistent as we move and transform the item. This mode is ideal |
| for this example, and works particularly well with OpenGL and OpenGL ES. |
| |
| \snippet graphicsview/padnavigator/roundrectitem.cpp 1 |
| |
| The \c pixmap property implementation simple returns the member pixmap, or |
| sets it and then calls \l{QGraphicsItem::update()}{update()}. |
| |
| \snippet graphicsview/padnavigator/roundrectitem.cpp 2 |
| |
| As the \l{QGraphicsItem::paint()}{paint()} implementation below draws a |
| simple drop shadow down and to the right of the item, we return a slightly |
| adjusted rectangle from \l{QGraphicsItem::boundingRect()}{boundingRect()}. |
| |
| \snippet graphicsview/padnavigator/roundrectitem.cpp 3 |
| |
| The \l{QGraphicsItem::paint()}{paint()} implementation starts by rendering |
| a semi transparent black round rectangle drop shadow, two units down and to |
| the right of the main item. |
| |
| \snippet graphicsview/padnavigator/roundrectitem.cpp 4 |
| |
| We then draw the "foreground" round rectangle itself. The fill depends on |
| the \c fill property; if true, we will with a plain QPalette::Window color. |
| We get the current brush from QApplication::palette(). We assign a single |
| unit wide pen for the stroke, assign the brush, and then draw the |
| rectangle. |
| |
| \snippet graphicsview/padnavigator/roundrectitem.cpp 5 |
| |
| If a pixmap has been assigned to the \e pixmap property, we draw this |
| pixmap in the center of the rectangle item. The pixmaps are scaled to match |
| the size of the icons; in arguably a better approach would have been to |
| store the icons with the right size in the first places. |
| |
| \snippet graphicsview/padnavigator/roundrectitem.cpp 6 |
| |
| Finally, for completeness we include the \c fill property implementation. |
| It returns the \c fill member variable's value, and when assigned to, it |
| calls \l{QGraphicsItem::update()}{update()}. |
| |
| As mentioned already, \c RoundRectItem is the base class for \c |
| FlippablePad, which is the class representing the tilting pad itself. We |
| will proceed to reviewing \c FlippablePad. |
| |
| \section1 FlippablePad Class Definition |
| |
| \c FlippablePad is, in addition to its inherited \c RoundRectItem |
| responsibilities, responsible for creating and managing a grid of icons. |
| |
| \snippet graphicsview/padnavigator/flippablepad.h 0 |
| |
| Its declaration is very simple: It inherits \c RoundRectItem and does not |
| need any special polymorphic behavior. It's suitable to declare its own |
| constructor, and a getter-function that allows \c PadNavigator to access |
| the icons in the grid by (row, column). |
| |
| The example has no "real" behavior or logic of any kind, and because of |
| that, the icons do not need to provide any \e behavior or special |
| interactions management. In a real application, however, it would be |
| natural for the \c FlippablePad and its icons to handle more of the |
| navigation logic. In this example, we have chosen to leave this to |
| the \c PadNavigator class, which we will get back to below. |
| |
| We will now review the \c FlippablePad implementation. This implementation |
| starts with two helper functions: \c boundsFromSize() and \c |
| posForLocation(): |
| |
| \snippet graphicsview/padnavigator/flippablepad.cpp 0 |
| |
| \c boundsForSize() takes a QSize argument, and returns the bounding |
| rectangle of the flippable pad item. The QSize determines how many rows and |
| columns the icon grid should have. Each icon is given 150x150 units of |
| space, and this determines the bounds. |
| |
| \snippet graphicsview/padnavigator/flippablepad.cpp 1 |
| |
| \c posForLocation() returns the position of an icon given its row and |
| column position. Like \c boundsForSize(), the function assumes each icon is |
| given 150x150 units of space, and that all icons are centered around the |
| flippable pad item's origin (0, 0). |
| |
| \snippet graphicsview/padnavigator/flippablepad.cpp 2 |
| |
| The \c FlippablePad constructor passes suitable bounds (using \c |
| boundsForSize()) and specific color to \c RoundRectItem's constructor. |
| |
| \snippet graphicsview/padnavigator/flippablepad.cpp 3 |
| |
| It then loads pixmaps from compiled-in resources to use for its icons. |
| QDirIterator is very useful in this context, as it allows us to fetch all |
| resource "*.png" files inside the \c :/images directory without explicitly |
| naming the files. |
| |
| We also make sure not to load more pixmaps than we need. |
| |
| \snippet graphicsview/padnavigator/flippablepad.cpp 4 |
| |
| Now that we have the pixmaps, we can create icons, position then and assign |
| pixmaps. We start by finding a suitable size and color for the icons, and |
| initializing a convenient grid structure for storing the icons. This \c |
| iconGrid is also used later to find the icon for a specific (column, row) |
| location. |
| |
| For each row and column in our grid, we proceed to constructing each icon |
| as an instance of \c RoundRectItem. The item is placed by using the \c |
| posForLocation() helper function. To make room for the slip-behind |
| selection item, we give each icon a \l{QGraphicsItem::zValue()}{Z-value} of |
| 1. The pixmaps are distributed to the icons in round-robin fasion. |
| |
| Again, this approach is only suitable for example purposes. In a real-life |
| application where each icon represents a specific action, it would be more |
| natural to assign the pixmaps directly, or that the icons themselves |
| provide suitable pixmaps. |
| |
| \snippet graphicsview/padnavigator/flippablepad.cpp 5 |
| |
| Finally, the \c iconAt() function returns a pointer to the icon at a |
| specific row and column. It makes a somewhat bold assumption that the input |
| is valid, which is fair because the \c PadNavigator class only calls this |
| function with correct input. |
| |
| We will now review the \c SplashItem class. |
| |
| \section1 SplashItem Class Definition |
| |
| The \c SplashItem class represents the "splash window", a semitransparent |
| white overlay with text that appears immediately after the application has |
| started, and disappears after pressing any key. The animation is controlled |
| by \c PadNavigator; this class is very simple by itself. |
| |
| \snippet graphicsview/padnavigator/splashitem.h 0 |
| |
| The class declaration shows that \c SplashItem inherits QGraphicsObject to |
| allow it to be controlled by QPropertyAnimation. It reimplements the |
| mandatory \l{QGraphicsItem::paint()}{paint()} and |
| \l{QGraphicsItem::boundingRect()}{boundingRect()} pure virtual functions, |
| and keeps a \c text member variable which will contain the information text |
| displayed on this splash item. |
| |
| Let's look at its implementation. |
| |
| \snippet graphicsview/padnavigator/splashitem.cpp 0 |
| |
| The constructor forwards to QGraphicsObject as expected, assigns a text |
| message to the \c text member variable, and enables |
| \l{QGraphicsItem::DeviceCoordinateCache}{DeviceCoordinateCache}. This cache |
| mode is suitable because the splash item only moves and is never |
| transformed, and because it contains text, it's important that it has a |
| pixel perfect visual appearance (in constrast to |
| \l{QGraphicsItem::ItemCoordinateCache}{ItemCoordinateCache}, where the |
| visual appearance is not as good). |
| |
| We use caching to avoid having to relayout and rerender the text for each |
| frame. An alterative approach would be to use the new QStaticText class. |
| |
| \snippet graphicsview/padnavigator/splashitem.cpp 1 |
| |
| \c SplashItem's bounding rectangle is fixed at (400x175). |
| |
| \snippet graphicsview/padnavigator/splashitem.cpp 2 |
| |
| The \l{QGraphicsItem::paint()}{paint()} implementation draws a clipped |
| round rectangle with a thick 2-unit border and a semi-transparent white |
| background. It proceeds to finding a suitable text area by adjusting the |
| splash item's bounding rectangle with 10 units in each side. The text is |
| rendered inside this rectangle, with top-left alignment, and with word |
| wrapping enabled. |
| |
| The main class now remains. We will proceed to reviewing \c PadNavigator. |
| |
| \section1 PadNavigator Class Definition |
| |
| \c PadNavigator represents the main window of our Pad Navigator Example |
| application. It creates and controls a somewhat complex state machine, and |
| several animations. Its class declaration is very simple: |
| |
| \snippet graphicsview/padnavigator/padnavigator.h 0 |
| |
| It inherits QGraphicsView and reimplements only one function: |
| \l{QGraphicsView::resizeEvent()}{resizeEvent()}, to ensure the scene is |
| scaled to fit inside the view when resizing the main window. |
| |
| The \c PadNavigator constructor takes a QSize argument that determines the |
| number or rows and columns in the grid. |
| |
| It also keeps a private member instance, \c form, which is the generated |
| code for the pad's back side item's QGraphicsProxyWidget-embedded form. |
| |
| \snippet graphicsview/padnavigator/padnavigator.cpp 0 |
| |
| \c PadNavigator's constructor is a bit long. In short, its job is to create |
| all items, including the \c FlippablePad, the \c SplashItem and the |
| QGraphicsProxyWidget \c backItem, and then to set up all animations, states |
| and transitions that control the behavior of the application. |
| |
| It starts out simple, by forwarding to QGraphicsView's constructor. |
| |
| \snippet graphicsview/padnavigator/padnavigator.cpp 1 |
| |
| The first item to be created is \c SplashItem. This is going to be a top-level |
| item in the scene, next to \c FlippablePad, and stacked on top of it, so we |
| assign it a \l{QGraphicsItem::zValue()}{Z-value} of 1. |
| |
| \snippet graphicsview/padnavigator/padnavigator.cpp 2 |
| |
| Now we construct the \c FlippablePad item, passing its column-row count to |
| its constructor. |
| |
| The pad is controlled by three transformations, and we create one |
| QGraphicsRotation object for each of these. |
| |
| \list |
| \li \c flipRotation: Rotates the grid around its Qt::YAxis. This rotation is |
| animated from 0 to 180, and eventually back, when enter is pressed on the |
| keyboard, flipping the pad around. |
| \li \c xRotation: Rotates the grid around its Qt::XAxis. This is used to |
| tilt the pad vertically corresponding to which item is currently selected. |
| This way, the selected item is always kept in front. |
| \li \c yRotation: Rotates the grid around its Qt::YAxis. This is used to |
| tilt the pad horizontally corresponding to which item is selected. This |
| way, the selected item is always kept in front. |
| \endlist |
| |
| The combination of all three rotations is assigned via |
| QGraphicsItem::setTransformations(). |
| |
| \snippet graphicsview/padnavigator/padnavigator.cpp 3 |
| |
| Now we construct the QGraphicsProxyWidget-embedded \c backItem. The proxy |
| widget is created as a child of the pad. We create a new QWidget and |
| populate it with the \c form member. To ensure the \c hostName line edit is |
| the first to receive input focus when this item is shown, we call |
| \l{QWidget::setFocus()}{setFocus()} immediately. This will not give the |
| widget focus right away; it will only prepare the item to automatically |
| receive focus once it is shown. |
| |
| The QWidget based form is embedded into the proxy widget. The proxy is |
| hidden initially; we only want to show it when the pad is rotated at least |
| 90 degrees, and we also rotate the proxy itself by 180 degrees. This way we |
| give the impression that the proxy widget is "behind" the flipped pad, when |
| in fact, it's actually \e{on top of it}. |
| |
| We enable \l{QGraphicsItem::ItemCoordinateCache}{ItemCoordinateCache} to |
| ensure the flip animation can run smoothly. |
| |
| \snippet graphicsview/padnavigator/padnavigator.cpp 4 |
| |
| We now create the selection item. This is simply another instance of \c |
| RoundRectItem that is slightly larger than the icons on the pad. We create |
| it as an immediate child of the \c FlippablePad, so the selection item is a |
| sibling to all the icons. By giving it a |
| \l{QGraphicsItem::zValue()}{Z-value} of 0.5 we ensure it will slide between |
| the pad and its icons. |
| |
| What follows now is a series of animation initializations. |
| |
| \snippet graphicsview/padnavigator/padnavigator.cpp 5 |
| |
| We begin with the animations that apply to the splash item. The first |
| animation, \c smoothSplashMove, ensures that the "y" property of \c splash |
| will be animated with a 250-millisecond duration |
| \l{QEasingCurve::InQuad}{InQuad} easing function. \c smoothSplashOpacity |
| ensures the opacity of \c splash eases in and out in 250 milliseconds. |
| |
| The values are assigned by \c PadNavigator's state machine, which is |
| created later. |
| |
| \snippet graphicsview/padnavigator/padnavigator.cpp 6 |
| |
| These are the animations that control the selection item's movement and the |
| \c xRotation and \c yRotation QGraphicsRotation objects that tilt the pad. |
| All animations have a duration of 125 milliseconds, and they all use the |
| \l{QEasingCurve::InOutQuad}{InOutQuad} easing function. |
| |
| \snippet graphicsview/padnavigator/padnavigator.cpp 7 |
| |
| We now create the animations that control the flip-effect when you press |
| the enter key. The main goal is to rotate the pad by 180 degrees or back. |
| |
| \list |
| \li \c smoothFlipRotation: Animates the main 180 degree rotation of the pad. |
| \li \c smoothFlipScale: Scales the pad out and then in again while the pad is rotating. |
| \li \c flipAnimation: A parallel animation group that ensures the above animations are run in parallel. |
| \endlist |
| |
| All animations are given a 500 millisecond duration and an |
| \l{QEasingCurve::InOutQuad}{InOutQuad} easing function. |
| |
| It's worth taking a close look at \c smoothFlipScale. This animation's |
| start and end values are both 1.0, but at animation step 0.5 the |
| animation's value is 0.7. This means that after 50% of the animation's |
| duration, or 250 milliseconds, the pad will be scaled down to 0.7x of its |
| original size, which gives a great visual effect while flipping. |
| |
| \snippet graphicsview/padnavigator/padnavigator.cpp 8 |
| |
| This section uses a trick to ensure that certain properties are assigned |
| precisely when the flip animation passes 50%, or 90 degrees, rotation. In |
| short, the pad's icons and selection item are all hidden, the pad's \c fill |
| property is enabled, and \c backItem is shown when flipping over. When |
| flipping back, the reverse properties are applied. |
| |
| The way this is achieved is by running a sequential animation in parallel |
| to the other animations. This sequence, dubbed \c setVariablesSequence, |
| starts with a 250 millisecond pause, and then executes several animations |
| with a duration of 0. Each animation will ensure that properties are set |
| immediate at this point. |
| |
| This approach can also be used to call functions or set any other |
| properties at a specific time while an animation is running. |
| |
| \snippet graphicsview/padnavigator/padnavigator.cpp 9 |
| |
| We will now create the state machine. The whole \c PadNavigator state |
| machinery is controlled by one single state machine that has a |
| straight-forward state structure. The state engine itself is created |
| as a child of the \c PadNavigator itself. We then create three top level |
| states: |
| |
| \list |
| \li \c splashState: The initial state where the splash item is visible. |
| \li \c frontState: The base state where the splash is gone and we can see |
| the front side of the pad, and navigate the selection item. |
| \li \c backState: The flipped state where the \c backItem is visible, and we |
| can interact with the QGraphicsProxyWidget-embedded form. |
| \endlist |
| |
| \snippet graphicsview/padnavigator/padnavigator.cpp 10 |
| |
| Each state assigns specific properties to objects on entry. Most |
| interesting perhaps is the assignment of the value 0.0 to the pad's \c |
| flipRotation angle property when in \c frontState, and 180.0 when in \c |
| backState. |
| |
| At the end of this section we register default animations with the state |
| engine; these animations will apply to their respective objects and |
| properties for any state transition. Otherwise it's common to assign |
| animations to specific transitions. |
| |
| Specifically, we use default animations to control the selection item's |
| movement and tilt rotations. The tilt rotations are set to 0 when the pad |
| is flipped, and restored back to their original values when flipped back. |
| |
| The \c splashState state is set as the initial state. This is required |
| before we start the state engine. We proceed with creating some |
| transitions. |
| |
| \snippet graphicsview/padnavigator/padnavigator.cpp 11 |
| |
| QEventTransition defines a very flexible transition type. You can use this |
| class to trigger a transition based on an object receiving an event of a |
| specific type. In this case, we would like to transition from \c |
| splashState into \c frontState if \c PadNavigator receives any key press |
| event (QEvent::KeyPress). |
| |
| We register the \c splashItem's animations to this transition to ensure they |
| are used to animate the item's movement and opacity. |
| |
| \snippet graphicsview/padnavigator/padnavigator.cpp 12 |
| |
| We use QKeyEventTransition to capture specific key events. In this case, we |
| detect that the user presses Qt::Key_Return or Qt::Key_Enter, and use this |
| to trigger transitions between \c frontState and backState. We register \c |
| flipAnimation, our complex parallel animation group, with these |
| transitions. |
| |
| We continue by defining the states for each of the icons in the grid. |
| |
| \snippet graphicsview/padnavigator/padnavigator.cpp 13 |
| |
| We will use state groups to control transitions between icons. Each icon |
| represents a \e substate of \c frontState. We will then define transitions |
| between the states by detecting key presses, using QKeyEventTransition. |
| |
| We start by creating all the substates, and at the same time we create a |
| temporary grid structure for the states to make it easier to find which |
| states represents icons that are up, down, left and to the right each |
| other. |
| |
| Once the first substate is known, we set this up as the initial substate of |
| \c frontState. We will use the (0, 0), or top-left, icon for the initial |
| substate. We initialze the selection item's position to be exactly where |
| the top-left icon is. |
| |
| \snippet graphicsview/padnavigator/padnavigator.cpp 14 |
| |
| We can now create four transitions for each icon. Each transition ensures |
| that we move to the state corresponding to which arrow key has been |
| pressed. It's clear from this techinique that we could design any other |
| specific transitions to and from each of the sub states depending on these |
| and other keys. |
| |
| \snippet graphicsview/padnavigator/padnavigator.cpp 15 |
| |
| Also, for each of the icons, we assign suitable values to the \c xRotation |
| and \c yRotation objects' "angle"-properties. If you recall, these |
| properties "tilt" the pad corresponding to which item is currently |
| selected. We ensure each icon is invisible when the pad is flipped, and |
| visible when the pad is not flipped. To ensure the visible property is |
| assigned at the right time, we add property-controlling animations to the |
| \c setVariableSequence animation defined earlier. |
| |
| \snippet graphicsview/padnavigator/padnavigator.cpp 16 |
| |
| We are now finished with all states, transitions, and animations. We now |
| create the scene that will contain all our items. The scene gets a defined |
| background pixmap, and we disable item indexing (as most items in this |
| scene are animated). We add our \c pad item to the scene, and use its |
| bounding rectangle to fixate the scene rectangle. This rectangle is used by |
| the view to find a suitable size for the application window. |
| |
| Then the scene is assigned to the view, or in our case, \c PadNavigator |
| itself. |
| |
| \snippet graphicsview/padnavigator/padnavigator.cpp 17 |
| |
| Now that the scene has received its final size, we can position the splash |
| item at the very top, find its fade-out position, and add it to the scene. |
| |
| \snippet graphicsview/padnavigator/padnavigator.cpp 18 |
| |
| The view toggles a few necessary properties: |
| |
| \list |
| \li It disables its scroll bars - this application has no use for scroll bars. |
| \li It assigns a minimum size. This is necessary to avoid numerical errors |
| in our fit-in-view \c resizeEvent() implementation. |
| \li It sets \l{QGraphicsView::FullViewportUpdate}{FullViewportUpdate}, to |
| ensure QGraphicsView doesn't spend time figuring out precisely what needs |
| to be redrawn. This application is very simple - if anything changes, |
| everything is updated. |
| \li It enables background caching - this makes no performance difference |
| with OpenGL, but without OpenGL it avoids unnecessary re-scaling of the |
| background pixmap. |
| \li It sets render hints that increase rendering quality. |
| \li If OpenGL is supported, a QOpenGLWidget viewport is assigned to the view. |
| \endlist |
| |
| Finally, we start the state engine. |
| |
| \snippet graphicsview/padnavigator/padnavigator.cpp 19 |
| |
| The \l{QGraphicsView::resizeEvent()}{resizeEvent()} implementation calls |
| the base implementation, and then calls QGraphicsView::fitInView() to scale |
| the scene so that it fits perfectly inside the view. |
| |
| By resizing the main application window, you can see this effect yourself. |
| The scene contents grow when you make the window larger, and shrink when |
| you make it smaller, while keeping the aspect ratio intact. |
| |
| \section1 The main() Function |
| |
| \snippet graphicsview/padnavigator/main.cpp 0 |
| |
| The \c main function creates the QApplication instance, uses |
| Q_INIT_RESOURCE to ensure our compiled-in resources aren't removed by the |
| linker, and then creates a 3x3 \c PadNavigator instance and shows it. |
| |
| Our flippable pad shows up with a suitable splash item once control returns |
| to the event loop. |
| |
| \section1 Performance Notes |
| |
| The example uses OpenGL if this is available, to achieve optimal |
| performance; otherwise perspective tranformations can be quite costly. |
| |
| Although this example does use QGraphicsProxyWidget to demonstrate |
| integration of Qt widget components integrated into Graphics View, using |
| QGraphicsProxyWidget comes with a performance penalty, and is therefore not |
| recommended for embedded development. |
| |
| This example uses extensive item caching to avoid rerendering of static |
| elements, at the expense of graphics memory. |
| */ |