Как сделать скриншот экрана и сохранить изображение в файл?

Задача заключается в создании скриншота и получения его из буфера обмена. Использую pyperclip, с текстом справляется хорошо, но вот принимает ли изображения - без понятия, как можно это реализовать?


Ответы (1 шт):

Автор решения: S. Nick

Попробуйте так:

from PyQt5.QtWidgets import (QApplication, QWidget, QPushButton, QLabel, 
                             QGridLayout, QFileDialog, QLayout, QHBoxLayout, QVBoxLayout,
                             QSizePolicy, QSystemTrayIcon, QStyle, QStackedWidget,
                             QMessageBox, QComboBox, QLineEdit, QStatusBar, 
                             QMainWindow, QToolBar, QErrorMessage, QAction)
from PyQt5.QtGui     import QPixmap, QIcon
from PyQt5.QtCore    import Qt, QTimer, QDateTime, pyqtSignal, QSize


class MainWindow(QWidget):
    def __init__(self, parent=None):
        super(MainWindow, self).__init__(parent)       
        self.parent = parent

        self.path = None                               # каталог где следует сохранить файл        
        self.preview_screen = QApplication.primaryScreen().grabWindow(0)  # делает скриншот

        self.settings()
        self.create_widgets()
        self.set_layout()

    # вставляет настройки в наше окно
    def settings(self):
        self.setGeometry(972, 395, 370, 270)
        self.setWindowTitle("Скриншот в PyQt5 - `Ctrl+P`")

    # создает и настраивает необходимые виджеты    
    def create_widgets(self):
        # создаем ярлык для отображения предварительного скриншота
        self.img_preview = QLabel()
        self.img_preview.setPixmap(self.preview_screen.scaled(self.img_preview.size(),
                                    Qt.KeepAspectRatio, Qt.SmoothTransformation))
        self.img_preview.setSizePolicy(QSizePolicy.Expanding, QSizePolicy.Expanding)
        self.img_preview.setAlignment(Qt.AlignCenter)
        self.img_preview.setMinimumSize(240, 160)                                    

        # создаем две кнопки                            
        self.btn_select_path = QPushButton("Выберите путь для сохранения screenshot", self)
        self.btn_new_screenshot  = QPushButton("Сделать screenshot")        
        self.btn_new_screenshot.setShortcut('Ctrl+P')                       

        # соединяем кнопки с их соответствующими методами
        self.btn_select_path.clicked.connect(self.select_path)         
        self.btn_new_screenshot.clicked.connect(self.new_screenshot)

    # Устанавливаем сетку и добавляем виджеты     
    def set_layout(self):  
        layout = QGridLayout()    
        self.setLayout(layout)
        layout.addWidget(self.img_preview)
        layout.addWidget(self.btn_select_path)
        layout.addWidget(self.btn_new_screenshot)

    # обновление изображения, присутствующего на ярлыке.
    def new_screenshot(self):
        if self.path == None or self.path == "":
            self.mess_ok1 = "Не указан путь для сохранения screenshot"
            self.mess_ok2 = "Выберите путь для сохранения screenshot."  
            self.downfin()
            return False    
        self.parent.hide()

        # после чего берем скриншот (как это делали в инициализаторе класса) и обновляем изображение в ярлыке
        # и, наконец, мы снова показываем наше окно.
        QTimer.singleShot(200, self.take_screenshot)    
        QTimer.singleShot(400, self.screen_save)  

    def take_screenshot(self):
        self.preview_screen = QApplication.primaryScreen().grabWindow(0)
        self.img_preview.setPixmap(self.preview_screen.scaled(self.img_preview.size(),
                                        Qt.KeepAspectRatio, Qt.SmoothTransformation))
        self.parent.show()                                 
        """
        Вышеупомянутый метод делает снимок экрана и сохраняет его в переменной self.preview_screen, 
        обновляет изображение на этикетке и, наконец, показывает наше приложение обратно. 
        """

    def screen_save(self):
        now = QDateTime.currentDateTime().toString(Qt.ISODate)
        now = now[0:4]+now[5:7]+now[8:10]+'-'+now[11:13]+now[14:16]+now[17:19]
        img = "%s/%s.png" % (self.path, now)                      
        _   = "PNG(*.png)"                                        
        self.preview_screen.save(img, "png")    

    def resizeEvent(self, event):
        scaledSize = self.preview_screen.size()                       
        scaledSize.scale(self.img_preview.size(), Qt.KeepAspectRatio)
        if not self.img_preview.pixmap() or scaledSize != self.img_preview.pixmap().size():
            self.updateScreenshotLabel()    

    def updateScreenshotLabel(self):
        self.img_preview.setPixmap(self.preview_screen.scaled(        
                self.img_preview.size(), Qt.KeepAspectRatio,
                Qt.SmoothTransformation))

    def select_path(self):                         # вызов диалогового окна выбора папки для сохранения  
        self.path = QFileDialog.getExistingDirectory(self,"Выбрать папку для сохранения screenshot")
        self.btn_select_path.setToolTip('<b>%s</b>' % self.path)

    def downfin(self):                           # для отображения сообщения о ходе выполнения программы
        # Инициализируем QSystemTrayIcon
        self.notifyIcon = QSystemTrayIcon(self)                                     
        self.notifyIcon.setIcon(self.style().standardIcon(QStyle.SP_DriveCDIcon))   
        self.notifyIcon.setVisible(True)     # (True) сохраняет, видна ли запись в системном tray/лотке
        self.notifyIcon.showMessage(self.mess_ok1, self.mess_ok2,
                                    QSystemTrayIcon.Information,3000)        


class RestartMainWindow(QWidget):
    def __init__(self, path, *args, **kwargs):
        super(RestartMainWindow, self).__init__(*args, **kwargs)
        self.setGeometry(972, 395, 370, 270)
        self.setWindowTitle('RestartMainWindow: '+path)

        if path == "Сделать Скриншот":
            currentWidget = MainWindow(self)                        
        layout = QVBoxLayout(self)        
        layout.addWidget(currentWidget)


if __name__ == "__main__":
    import sys
    from PyQt5.QtWidgets import QApplication
    app = QApplication(sys.argv)
    w   = RestartMainWindow("Сделать Скриншот")
    w.show()
    sys.exit(app.exec_())

введите сюда описание изображения

→ Ссылка