source: trunk/doc/src/examples/screenshot.qdoc@ 651

Last change on this file since 651 was 651, checked in by Dmitry A. Kuminov, 15 years ago

trunk: Merged in qt 4.6.2 sources.

File size: 11.3 KB
Line 
1/****************************************************************************
2**
3** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies).
4** All rights reserved.
5** Contact: Nokia Corporation ([email protected])
6**
7** This file is part of the documentation of the Qt Toolkit.
8**
9** $QT_BEGIN_LICENSE:LGPL$
10** Commercial Usage
11** Licensees holding valid Qt Commercial licenses may use this file in
12** accordance with the Qt Commercial License Agreement provided with the
13** Software or, alternatively, in accordance with the terms contained in
14** a written agreement between you and Nokia.
15**
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.
23**
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.
27**
28** GNU General Public License Usage
29** Alternatively, this file may be used under the terms of the GNU
30** General Public License version 3.0 as published by the Free Software
31** Foundation and appearing in the file LICENSE.GPL included in the
32** packaging of this file. Please review the following information to
33** ensure the GNU General Public License version 3.0 requirements will be
34** met: http://www.gnu.org/copyleft/gpl.html.
35**
36** If you have questions regarding the use of this file, please contact
37** Nokia at [email protected].
38** $QT_END_LICENSE$
39**
40****************************************************************************/
41
42/*!
43 \example desktop/screenshot
44 \title Screenshot Example
45
46 The Screenshot example shows how to take a screenshot of the
47 desktop using QApplication and QDesktopWidget. It also shows how
48 to use QTimer to provide a single-shot timer, and how to
49 reimplement the QWidget::resizeEvent() event handler to make sure
50 that an application resizes smoothly and without data loss.
51
52 \image screenshot-example.png
53
54 With the application the users can take a screenshot of their
55 desktop. They are provided with a couple of options:
56
57 \list
58 \o Delaying the screenshot, giving them time to rearrange
59 their desktop.
60 \o Hiding the application's window while the screenshot is taken.
61 \endlist
62
63 In addition the application allows the users to save their
64 screenshot if they want to.
65
66 \section1 Screenshot Class Definition
67
68 \snippet examples/desktop/screenshot/screenshot.h 0
69
70 The \c Screenshot class inherits QWidget and is the application's
71 main widget. It displays the application options and a preview of
72 the screenshot.
73
74 We reimplement the QWidget::resizeEvent() function to make sure
75 that the preview of the screenshot scales properly when the user
76 resizes the application widget. We also need several private slots
77 to facilitate the options:
78
79 \list
80 \o The \c newScreenshot() slot prepares a new screenshot.
81 \o The \c saveScreenshot() slot saves the last screenshot.
82 \o The \c shootScreen() slot takes the screenshot.
83 \o The \c updateCheckBox() slot enables or disables the
84 \gui {Hide This Window} option.
85 \endlist
86
87 We also declare some private functions: We use the \c
88 createOptionsGroupBox(), \c createButtonsLayout() and \c
89 createButton() functions when we construct the widget. And we call
90 the private \c updateScreenshotLabel() function whenever a new
91 screenshot is taken or when a resize event changes the size of the
92 screenshot preview label.
93
94 In addition we need to store the screenshot's original pixmap. The
95 reason is that when we display the preview of the screenshot, we
96 need to scale its pixmap, storing the original we make sure that
97 no data are lost in that process.
98
99 \section1 Screenshot Class Implementation
100
101 \snippet examples/desktop/screenshot/screenshot.cpp 0
102
103 In the constructor we first create the QLabel displaying the
104 screenshot preview.
105
106 We set the QLabel's size policy to be QSizePolicy::Expanding both
107 horizontally and vertically. This means that the QLabel's size
108 hint is a sensible size, but the widget can be shrunk and still be
109 useful. Also, the widget can make use of extra space, so it should
110 get as much space as possible. Then we make sure the QLabel is
111 aligned in the center of the \c Screenshot widget, and set its
112 minimum size.
113
114 We create the applications's buttons and the group box containing
115 the application's options, and put it all into a main
116 layout. Finally we take the initial screenshot, and set the inital
117 delay and the window title, before we resize the widget to a
118 suitable size.
119
120 \snippet examples/desktop/screenshot/screenshot.cpp 1
121
122 The \c resizeEvent() function is reimplemented to receive the
123 resize events dispatched to the widget. The purpose is to scale
124 the preview screenshot pixmap without deformation of its content,
125 and also make sure that the application can be resized smoothly.
126
127 To achieve the first goal, we scale the screenshot pixmap using
128 Qt::KeepAspectRatio. We scale the pixmap to a rectangle as large
129 as possible inside the current size of the screenshot preview
130 label, preserving the aspect ratio. This means that if the user
131 resizes the application window in only one direction, the preview
132 screenshot keeps the same size.
133
134 To reach our second goal, we make sure that the preview screenshot
135 only is repainted (using the private \c updateScreenshotLabel()
136 function) when it actually changes its size.
137
138 \snippet examples/desktop/screenshot/screenshot.cpp 2
139
140 The private \c newScreenshot() slot is called when the user
141 requests a new screenshot; but the slot only prepares a new
142 screenshot.
143
144 First we see if the \gui {Hide This Window} option is checked, if
145 it is we hide the \c Screenshot widget. Then we disable the \gui
146 {New Screenshot} button, to make sure the user only can request
147 one screenshot at a time.
148
149 We create a timer using the QTimer class which provides repetitive
150 and single-shot timers. We set the timer to time out only once,
151 using the static QTimer::singleShot() function. This function
152 calls the private \c shootScreen() slot after the time interval
153 specified by the \gui {Screenshot Delay} option. It is \c
154 shootScreen() that actually performs the screenshot.
155
156 \snippet examples/desktop/screenshot/screenshot.cpp 3
157
158 The \c saveScreenshot() slot is called when the user push the \gui
159 Save button, and it presents a file dialog using the QFileDialog
160 class.
161
162 QFileDialog enables a user to traverse the file system in order to
163 select one or many files or a directory. The easiest way to create
164 a QFileDialog is to use the convenience static
165 functions.
166
167 We define the default file format to be png, and we make the file
168 dialog's initial path the path the application is run from. We
169 create the file dialog using the static
170 QFileDialog::getSaveFileName() function which returns a file name
171 selected by the user. The file does not have to exist. If the file
172 name is valid, we use the QPixmap::save() function to save the
173 screenshot's original pixmap in that file.
174
175 \snippet examples/desktop/screenshot/screenshot.cpp 4
176
177 The \c shootScreen() slot is called to take the screenshot. If the
178 user has chosen to delay the screenshot, we make the application
179 beep when the screenshot is taken using the static
180 QApplication::beep() function.
181
182 The QApplication class manages the GUI application's control flow
183 and main settings. It contains the main event loop, where all
184 events from the window system and other sources are processed and
185 dispatched.
186
187 \snippet examples/desktop/screenshot/screenshot.cpp 5
188
189 We take the screenshot using the static QPixmap::grabWindow()
190 function. The function grabs the contents of the window passed as
191 an argument, makes a pixmap out of it and returns that pixmap.
192
193 We identify the argument window using the QWidget::winID()
194 function which returns the window system identifier. Here it
195 returns the identifier of the current QDesktopWidget retrieved by
196 the QApplication::desktop() function. The QDesktopWidget class
197 provides access to screen information, and inherits
198 QWidget::winID().
199
200 We update the screenshot preview label using the private \c
201 updateScreenshotLabel() function. Then we enable the \gui {New
202 Screenshot} button, and finally we make the \c Screenshot widget
203 visible if it was hidden during the screenshot.
204
205 \snippet examples/desktop/screenshot/screenshot.cpp 6
206
207 The \gui {Hide This Window} option is enabled or disabled
208 depending on the delay of the screenshot. If there is no delay,
209 the application window cannot be hidden and the option's checkbox
210 is disabled.
211
212 The \c updateCheckBox() slot is called whenever the user changes
213 the delay using the \gui {Screenshot Delay} option.
214
215 \snippet examples/desktop/screenshot/screenshot.cpp 7
216
217 The private \c createOptionsGroupBox() function is called from the
218 constructor.
219
220 First we create a group box that will contain all of the options'
221 widgets. Then we create a QSpinBox and a QLabel for the \gui
222 {Screenshot Delay} option, and connect the spinbox to the \c
223 updateCheckBox() slot. Finally, we create a QCheckBox for the \gui
224 {Hide This Window} option, add all the options' widgets to a
225 QGridLayout and install the layout on the group box.
226
227 Note that we don't have to specify any parents for the widgets
228 when we create them. The reason is that when we add a widget to a
229 layout and install the layout on another widget, the layout's
230 widgets are automatically reparented to the widget the layout is
231 installed on.
232
233 \snippet examples/desktop/screenshot/screenshot.cpp 8
234
235 The private \c createButtonsLayout() function is called from the
236 constructor. We create the application's buttons using the private
237 \c createButton() function, and add them to a QHBoxLayout.
238
239 \snippet examples/desktop/screenshot/screenshot.cpp 9
240
241 The private \c createButton() function is called from the \c
242 createButtonsLayout() function. It simply creates a QPushButton
243 with the provided text, connects it to the provided receiver and
244 slot, and returns a pointer to the button.
245
246 \snippet examples/desktop/screenshot/screenshot.cpp 10
247
248 The private \c updateScreenshotLabel() function is called whenever
249 the screenshot changes, or when a resize event changes the size of
250 the screenshot preview label. It updates the screenshot preview's
251 label using the QLabel::setPixmap() and QPixmap::scaled()
252 functions.
253
254 QPixmap::scaled() returns a copy of the given pixmap scaled to a
255 rectangle of the given size according to the given
256 Qt::AspectRatioMode and Qt::TransformationMode.
257
258 We scale the original pixmap to fit the current screenshot label's
259 size, preserving the aspect ratio and giving the resulting pixmap
260 smoothed edges.
261*/
262
Note: See TracBrowser for help on using the repository browser.