1#!/usr/bin/env python
2
3
4#############################################################################
5##
6## Copyright (C) 2013 Riverbank Computing Limited.
7## Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies).
8## All rights reserved.
9##
10## This file is part of the examples of PyQt.
11##
12## $QT_BEGIN_LICENSE:BSD$
13## You may use this file under the terms of the BSD license as follows:
14##
15## "Redistribution and use in source and binary forms, with or without
16## modification, are permitted provided that the following conditions are
17## met:
18##   * Redistributions of source code must retain the above copyright
19##     notice, this list of conditions and the following disclaimer.
20##   * Redistributions in binary form must reproduce the above copyright
21##     notice, this list of conditions and the following disclaimer in
22##     the documentation and/or other materials provided with the
23##     distribution.
24##   * Neither the name of Nokia Corporation and its Subsidiary(-ies) nor
25##     the names of its contributors may be used to endorse or promote
26##     products derived from this software without specific prior written
27##     permission.
28##
29## THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
30## "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
31## LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
32## A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
33## OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
34## SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
35## LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
36## DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
37## THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
38## (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
39## OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE."
40## $QT_END_LICENSE$
41##
42#############################################################################
43
44
45from PyQt5.QtCore import QDir, Qt, QTimer
46from PyQt5.QtGui import QPixmap
47from PyQt5.QtWidgets import (QApplication, QCheckBox, QFileDialog, QGridLayout,
48        QGroupBox, QHBoxLayout, QLabel, QPushButton, QSizePolicy, QSpinBox,
49        QVBoxLayout, QWidget)
50
51
52class Screenshot(QWidget):
53    def __init__(self):
54        super(Screenshot, self).__init__()
55
56        self.screenshotLabel = QLabel()
57        self.screenshotLabel.setSizePolicy(QSizePolicy.Expanding,
58                QSizePolicy.Expanding)
59        self.screenshotLabel.setAlignment(Qt.AlignCenter)
60        self.screenshotLabel.setMinimumSize(240, 160)
61
62        self.createOptionsGroupBox()
63        self.createButtonsLayout()
64
65        mainLayout = QVBoxLayout()
66        mainLayout.addWidget(self.screenshotLabel)
67        mainLayout.addWidget(self.optionsGroupBox)
68        mainLayout.addLayout(self.buttonsLayout)
69        self.setLayout(mainLayout)
70
71        self.shootScreen()
72        self.delaySpinBox.setValue(5)
73
74        self.setWindowTitle("Screenshot")
75        self.resize(300, 200)
76
77    def resizeEvent(self, event):
78        scaledSize = self.originalPixmap.size()
79        scaledSize.scale(self.screenshotLabel.size(), Qt.KeepAspectRatio)
80        if not self.screenshotLabel.pixmap() or scaledSize != self.screenshotLabel.pixmap().size():
81            self.updateScreenshotLabel()
82
83    def newScreenshot(self):
84        if self.hideThisWindowCheckBox.isChecked():
85            self.hide()
86        self.newScreenshotButton.setDisabled(True)
87
88        QTimer.singleShot(self.delaySpinBox.value() * 1000,
89                self.shootScreen)
90
91    def saveScreenshot(self):
92        format = 'png'
93        initialPath = QDir.currentPath() + "/untitled." + format
94
95        fileName, _ = QFileDialog.getSaveFileName(self, "Save As", initialPath,
96                "%s Files (*.%s);;All Files (*)" % (format.upper(), format))
97        if fileName:
98            self.originalPixmap.save(fileName, format)
99
100    def shootScreen(self):
101        if self.delaySpinBox.value() != 0:
102            QApplication.instance().beep()
103
104        screen = QApplication.primaryScreen()
105        if screen is not None:
106            self.originalPixmap = screen.grabWindow(0)
107        else:
108            self.originalPixmap = QPixmap()
109
110        self.updateScreenshotLabel()
111
112        self.newScreenshotButton.setDisabled(False)
113        if self.hideThisWindowCheckBox.isChecked():
114            self.show()
115
116    def updateCheckBox(self):
117        if self.delaySpinBox.value() == 0:
118            self.hideThisWindowCheckBox.setDisabled(True)
119        else:
120            self.hideThisWindowCheckBox.setDisabled(False)
121
122    def createOptionsGroupBox(self):
123        self.optionsGroupBox = QGroupBox("Options")
124
125        self.delaySpinBox = QSpinBox()
126        self.delaySpinBox.setSuffix(" s")
127        self.delaySpinBox.setMaximum(60)
128        self.delaySpinBox.valueChanged.connect(self.updateCheckBox)
129
130        self.delaySpinBoxLabel = QLabel("Screenshot Delay:")
131
132        self.hideThisWindowCheckBox = QCheckBox("Hide This Window")
133
134        optionsGroupBoxLayout = QGridLayout()
135        optionsGroupBoxLayout.addWidget(self.delaySpinBoxLabel, 0, 0)
136        optionsGroupBoxLayout.addWidget(self.delaySpinBox, 0, 1)
137        optionsGroupBoxLayout.addWidget(self.hideThisWindowCheckBox, 1, 0, 1, 2)
138        self.optionsGroupBox.setLayout(optionsGroupBoxLayout)
139
140    def createButtonsLayout(self):
141        self.newScreenshotButton = self.createButton("New Screenshot",
142                self.newScreenshot)
143
144        self.saveScreenshotButton = self.createButton("Save Screenshot",
145                self.saveScreenshot)
146
147        self.quitScreenshotButton = self.createButton("Quit", self.close)
148
149        self.buttonsLayout = QHBoxLayout()
150        self.buttonsLayout.addStretch()
151        self.buttonsLayout.addWidget(self.newScreenshotButton)
152        self.buttonsLayout.addWidget(self.saveScreenshotButton)
153        self.buttonsLayout.addWidget(self.quitScreenshotButton)
154
155    def createButton(self, text, member):
156        button = QPushButton(text)
157        button.clicked.connect(member)
158        return button
159
160    def updateScreenshotLabel(self):
161        self.screenshotLabel.setPixmap(self.originalPixmap.scaled(
162                self.screenshotLabel.size(), Qt.KeepAspectRatio,
163                Qt.SmoothTransformation))
164
165
166if __name__ == '__main__':
167
168    import sys
169
170    app = QApplication(sys.argv)
171    screenshot = Screenshot()
172    screenshot.show()
173    sys.exit(app.exec_())
174