diff options
Diffstat (limited to 'examples/widgets/doc/imageviewer.qdoc')
-rw-r--r-- | examples/widgets/doc/imageviewer.qdoc | 326 |
1 files changed, 326 insertions, 0 deletions
diff --git a/examples/widgets/doc/imageviewer.qdoc b/examples/widgets/doc/imageviewer.qdoc new file mode 100644 index 0000000000..8f8e238046 --- /dev/null +++ b/examples/widgets/doc/imageviewer.qdoc @@ -0,0 +1,326 @@ +/**************************************************************************** +** +** Copyright (C) 2012 Nokia Corporation and/or its subsidiary(-ies). +** Contact: http://www.qt-project.org/ +** +** This file is part of the documentation of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:FDL$ +** GNU Free Documentation License +** 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. +** +** Other Usage +** Alternatively, this file may be used in accordance with the terms +** and conditions contained in a signed written agreement between you +** and Nokia. +** +** +** +** +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +/*! + \example widgets/imageviewer + \title Image Viewer Example + + The example shows how to combine QLabel and QScrollArea to + display an image. QLabel is typically used for displaying text, + but it can also display an image. QScrollArea provides a + scrolling view around another widget. If the child widget exceeds + the size of the frame, QScrollArea automatically provides scroll + bars. + + The example demonstrates how QLabel's ability to scale its + contents (QLabel::scaledContents), and QScrollArea's ability to + automatically resize its contents (QScrollArea::widgetResizable), + can be used to implement zooming and scaling features. In + addition the example shows how to use QPainter to print an image. + + \image imageviewer-example.png Screenshot of the Image Viewer example + + With the Image Viewer application, the users can view an image of + their choice. The \uicontrol File menu gives the user the possibility + to: + + \list + \li \uicontrol{Open...} - Open an image file + \li \uicontrol{Print...} - Print an image + \li \uicontrol{Exit} - Exit the application + \endlist + + Once an image is loaded, the \uicontrol View menu allows the users to: + + \list + \li \uicontrol{Zoom In} - Scale the image up by 25% + \li \uicontrol{Zoom Out} - Scale the image down by 25% + \li \uicontrol{Normal Size} - Show the image at its original size + \li \uicontrol{Fit to Window} - Stretch the image to occupy the entire window + \endlist + + In addition the \uicontrol Help menu provides the users with information + about the Image Viewer example in particular, and about Qt in + general. + + \section1 ImageViewer Class Definition + + \snippet widgets/imageviewer/imageviewer.h 0 + + The \c ImageViewer class inherits from QMainWindow. We reimplement + the constructor, and create several private slots to facilitate + the menu entries. In addition we create four private functions. + + We use \c createActions() and \c createMenus() when constructing + the \c ImageViewer widget. We use the \c updateActions() function + to update the menu entries when a new image is loaded, or when + the \uicontrol {Fit to Window} option is toggled. The zoom slots use \c + scaleImage() to perform the zooming. In turn, \c + scaleImage() uses \c adjustScrollBar() to preserve the focal point after + scaling an image. + + \section1 ImageViewer Class Implementation + + \snippet widgets/imageviewer/imageviewer.cpp 0 + + In the constructor we first create the label and the scroll area. + + We set \c {imageLabel}'s size policy to \l + {QSizePolicy::Ignored}{ignored}, making the users able to scale + the image to whatever size they want when the \uicontrol {Fit to Window} + option is turned on. Otherwise, the default size polizy (\l + {QSizePolicy::Preferred}{preferred}) will make scroll bars appear + when the scroll area becomes smaller than the label's minimum size + hint. + + We ensure that the label will scale its contents to fill all + available space, to enable the image to scale properly when + zooming. If we omitted to set the \c {imageLabel}'s \l + {QLabel::scaledContents}{scaledContents} property, zooming in + would enlarge the QLabel, but leave the pixmap at + its original size, exposing the QLabel's background. + + We make \c imageLabel the scroll area's child widget, and we make + \c scrollArea the central widget of the QMainWindow. At the end + we create the associated actions and menus, and customize the \c + {ImageViewer}'s appearance. + + \snippet widgets/imageviewer/imageviewer.cpp 1 + \snippet widgets/imageviewer/imageviewer.cpp 2 + + In the \c open() slot, we show a file dialog to the user. The + easiest way to create a QFileDialog is to use the static + convenience functions. QFileDialog::getOpenFileName() returns an + existing file selected by the user. If the user presses \uicontrol + Cancel, QFileDialog returns an empty string. + + Unless the file name is a empty string, we check if the file's + format is an image format by constructing a QImage which tries to + load the image from the file. If the constructor returns a null + image, we use a QMessageBox to alert the user. + + The QMessageBox class provides a modal dialog with a short + message, an icon, and some buttons. As with QFileDialog the + easiest way to create a QMessageBox is to use its static + convenience functions. QMessageBox provides a range of different + messages arranged along two axes: severity (question, + information, warning and critical) and complexity (the number of + necessary response buttons). In this particular example an + information message with an \uicontrol OK button (the default) is + sufficient, since the message is part of a normal operation. + + \snippet widgets/imageviewer/imageviewer.cpp 3 + \snippet widgets/imageviewer/imageviewer.cpp 4 + + If the format is supported, we display the image in \c imageLabel + by setting the label's \l {QLabel::pixmap}{pixmap}. Then we enable + the \uicontrol Print and \uicontrol {Fit to Window} menu entries and update + the rest of the view menu entries. The \uicontrol Open and \uicontrol Exit + entries are enabled by default. + + If the \uicontrol {Fit to Window} option is turned off, the + QScrollArea::widgetResizable property is \c false and it is + our responsibility (not QScrollArea's) to give the QLabel a + reasonable size based on its contents. We call + \{QWidget::adjustSize()}{adjustSize()} to achieve this, which is + essentially the same as + + \snippet doc/src/snippets/code/doc_src_examples_imageviewer.cpp 0 + + In the \c print() slot, we first make sure that an image has been + loaded into the application: + + \snippet widgets/imageviewer/imageviewer.cpp 5 + \snippet widgets/imageviewer/imageviewer.cpp 6 + + If the application is built in debug mode, the \c Q_ASSERT() macro + will expand to + + \snippet doc/src/snippets/code/doc_src_examples_imageviewer.cpp 1 + + In release mode, the macro simply disappear. The mode can be set + in the application's \c .pro file. One way to do so is to add an + option to \uicontrol qmake when building the application: + + \snippet doc/src/snippets/code/doc_src_examples_imageviewer.qdoc 2 + + or + + \snippet doc/src/snippets/code/doc_src_examples_imageviewer.qdoc 3 + + Another approach is to add this line directly to the \c .pro + file. + + \snippet widgets/imageviewer/imageviewer.cpp 7 + \snippet widgets/imageviewer/imageviewer.cpp 8 + + Then we present a print dialog allowing the user to choose a + printer and to set a few options. We construct a painter with a + QPrinter as the paint device. We set the painter's window + and viewport in such a way that the image is as large as possible + on the paper, but without altering its + \l{Qt::KeepAspectRatio}{aspect ratio}. + + In the end we draw the pixmap at position (0, 0). + + \snippet widgets/imageviewer/imageviewer.cpp 9 + \snippet widgets/imageviewer/imageviewer.cpp 10 + + We implement the zooming slots using the private \c scaleImage() + function. We set the scaling factors to 1.25 and 0.8, + respectively. These factor values ensure that a \uicontrol {Zoom In} + action and a \uicontrol {Zoom Out} action will cancel each other (since + 1.25 * 0.8 == 1), and in that way the normal image size can be + restored using the zooming features. + + The screenshots below show an image in its normal size, and the + same image after zooming in: + + \table + \row + \li \inlineimage imageviewer-original_size.png + \li \inlineimage imageviewer-zoom_in_1.png + \li \inlineimage imageviewer-zoom_in_2.png + \endtable + + \snippet widgets/imageviewer/imageviewer.cpp 11 + \snippet widgets/imageviewer/imageviewer.cpp 12 + + When zooming, we use the QLabel's ability to scale its contents. + Such scaling doesn't change the actual size hint of the contents. + And since the \l {QLabel::adjustSize()}{adjustSize()} function + use those size hint, the only thing we need to do to restore the + normal size of the currently displayed image is to call \c + adjustSize() and reset the scale factor to 1.0. + + \snippet widgets/imageviewer/imageviewer.cpp 13 + \snippet widgets/imageviewer/imageviewer.cpp 14 + + The \c fitToWindow() slot is called each time the user toggled + the \uicontrol {Fit to Window} option. If the slot is called to turn on + the option, we tell the scroll area to resize its child widget + with the QScrollArea::setWidgetResizable() function. Then we + disable the \uicontrol {Zoom In}, \uicontrol {Zoom Out} and \uicontrol {Normal + Size} menu entries using the private \c updateActions() function. + + If the \l {QScrollArea::widgetResizable} property is set to \c + false (the default), the scroll area honors the size of its child + widget. If this property is set to \c true, the scroll area will + automatically resize the widget in order to avoid scroll bars + where they can be avoided, or to take advantage of extra space. + But the scroll area will honor the minimum size hint of its child + widget independent of the widget resizable property. So in this + example we set \c {imageLabel}'s size policy to \l + {QSizePolicy::Ignored}{ignored} in the constructor, to avoid that + scroll bars appear when the scroll area becomes smaller than the + label's minimum size hint. + + The screenshots below shows an image in its normal size, and the + same image with the \uicontrol {Fit to window} option turned on. + Enlarging the window will stretch the image further, as shown in + the third screenshot. + + \table + \row + \li \inlineimage imageviewer-original_size.png + \li \inlineimage imageviewer-fit_to_window_1.png + \li \inlineimage imageviewer-fit_to_window_2.png + \endtable + + If the slot is called to turn off the option, the + {QScrollArea::setWidgetResizable} property is set to \c false. We + also restore the image pixmap to its normal size by adjusting the + label's size to its content. And in the end we update the view + menu entries. + + \snippet widgets/imageviewer/imageviewer.cpp 15 + \snippet widgets/imageviewer/imageviewer.cpp 16 + + We implement the \c about() slot to create a message box + describing what the example is designed to show. + + \snippet widgets/imageviewer/imageviewer.cpp 17 + \snippet widgets/imageviewer/imageviewer.cpp 18 + + In the private \c createAction() function, we create the + actions providing the application features. + + We assign a short-cut key to each action and connect them to the + appropriate slots. We only enable the \c openAct and \c exitAct at + the time of creation, the others are updated once an image has + been loaded into the application. In addition we make the \c + fitToWindowAct \l {QAction::checkable}{checkable}. + + \snippet widgets/imageviewer/imageviewer.cpp 19 + \snippet widgets/imageviewer/imageviewer.cpp 20 + + In the private \c createMenu() function, we add the previously + created actions to the \uicontrol File, \uicontrol View and \uicontrol Help menus. + + The QMenu class provides a menu widget for use in menu bars, + context menus, and other popup menus. The QMenuBar class provides + a horizontal menu bar that consists of a list of pull-down menu + items. So at the end we put the menus in the \c {ImageViewer}'s + menu bar which we retrieve with the QMainWindow::menuBar() + function. + + \snippet widgets/imageviewer/imageviewer.cpp 21 + \snippet widgets/imageviewer/imageviewer.cpp 22 + + The private \c updateActions() function enables or disables the + \uicontrol {Zoom In}, \uicontrol {Zoom Out} and \uicontrol {Normal Size} menu + entries depending on whether the \uicontrol {Fit to Window} option is + turned on or off. + + \snippet widgets/imageviewer/imageviewer.cpp 23 + \snippet widgets/imageviewer/imageviewer.cpp 24 + + In \c scaleImage(), we use the \c factor parameter to calculate + the new scaling factor for the displayed image, and resize \c + imageLabel. Since we set the + \l{QLabel::scaledContents}{scaledContents} property to \c true in + the constructor, the call to QWidget::resize() will scale the + image displayed in the label. We also adjust the scroll bars to + preserve the focal point of the image. + + At the end, if the scale factor is less than 33.3% or greater + than 300%, we disable the respective menu entry to prevent the + image pixmap from becoming too large, consuming too much + resources in the window system. + + \snippet widgets/imageviewer/imageviewer.cpp 25 + \snippet widgets/imageviewer/imageviewer.cpp 26 + + Whenever we zoom in or out, we need to adjust the scroll bars in + consequence. It would have been tempting to simply call + + \snippet doc/src/snippets/code/doc_src_examples_imageviewer.cpp 4 + + but this would make the top-left corner the focal point, not the + center. Therefore we need to take into account the scroll bar + handle's size (the \l{QScrollBar::pageStep}{page step}). +*/ |