콘텐츠로 건너뛰기
» PyQt를 사용하여 스크린샷 도구 만들기

PyQt를 사용하여 스크린샷 도구 만들기

이번 블로그 글에서는 PyQt를 사용하여 간단한 스크린샷 도구를 만드는 과정을 설명하겠습니다. 이 도구는 사용자가 전체 화면을 스크린샷으로 찍고, 딤 처리된 오버레이를 적용한 후, 특정 영역을 선택하여 WebP 형식으로 70% 품질로 저장할 수 있게 해줍니다. 그럼 시작해보겠습니다!

단계 1: 프로젝트 설정

먼저 PyQt5를 설치해야 합니다. 설치하지 않았다면 아래 명령어를 사용하여 설치할 수 있습니다.

pip install PyQt5

단계 2: 메인 윈도우 만들기

먼저, 메인 윈도우를 설정하고 버튼을 추가하여 오버레이를 표시하도록 합니다.

import sys
from PyQt5.QtWidgets import QApplication, QMainWindow, QPushButton, QVBoxLayout, QWidget
from PyQt5.QtGui import QPixmap, QScreen, QPainter, QColor
from PyQt5.QtCore import Qt, QRect, QPoint, QSize

class MainWindow(QMainWindow):
    def __init__(self):
        super().__init__()
        self.setWindowTitle("Screenshot Tool")
        self.setGeometry(100, 100, 800, 600)

        # Set up the main layout
        main_layout = QVBoxLayout()

        # Create the screenshot button
        screenshot_button = QPushButton("Take Screenshot")
        screenshot_button.clicked.connect(self.show_overlay)

        main_layout.addWidget(screenshot_button)

        # Set the central widget
        container = QWidget()
        container.setLayout(main_layout)
        self.setCentralWidget(container)

    def show_overlay(self):
        screen = QApplication.primaryScreen()
        original_screenshot = screen.grabWindow(0)

        # Create a dimmed overlay on top of the screenshot
        dimmed_pixmap = QPixmap(original_screenshot.size())
        dimmed_pixmap.fill(Qt.transparent)
        painter = QPainter(dimmed_pixmap)
        painter.drawPixmap(0, 0, original_screenshot)
        painter.fillRect(original_screenshot.rect(), QColor(0, 0, 0, 128))  # Semi-transparent black overlay
        painter.end()

        self.overlay = Overlay(original_screenshot, dimmed_pixmap, self)
        self.overlay.showFullScreen()

if __name__ == "__main__":
    app = QApplication(sys.argv)
    window = MainWindow()
    window.show()
    sys.exit(app.exec_())

위 코드는 메인 윈도우를 설정하고, “Take Screenshot” 버튼을 추가하여 클릭 시 전체 화면을 스크린샷으로 찍고 딤 처리된 오버레이를 표시하도록 합니다.

단계 3: 오버레이 클래스 만들기

오버레이 클래스는 딤 처리된 스크린샷을 표시하고, 사용자가 마우스로 선택한 영역을 캡처하여 저장하는 기능을 구현합니다.

class Overlay(QWidget):
    def __init__(self, original_pixmap, dimmed_pixmap, parent=None):
        super().__init__(parent)
        self.setWindowFlags(Qt.FramelessWindowHint | Qt.WindowStaysOnTopHint | Qt.Tool)
        self.setGeometry(QApplication.primaryScreen().geometry())
        self.original_pixmap = original_pixmap
        self.dimmed_pixmap = dimmed_pixmap

        # QLabel to display the dimmed screenshot
        self.label = QLabel(self)
        self.label.setPixmap(self.dimmed_pixmap)
        self.label.setGeometry(self.rect())

        self.rubber_band = QRubberBand(QRubberBand.Rectangle, self)
        self.start_pos = QPoint()
        self.end_pos = QPoint()

    def mousePressEvent(self, event):
        if event.button() == Qt.LeftButton:
            self.start_pos = event.pos()
            self.rubber_band.setGeometry(QRect(self.start_pos, QSize()))
            self.rubber_band.show()

    def mouseMoveEvent(self, event):
        if not self.start_pos.isNull():
            self.rubber_band.setGeometry(QRect(self.start_pos, event.pos()).normalized())

    def mouseReleaseEvent(self, event):
        if event.button() == Qt.LeftButton:
            self.end_pos = event.pos()
            self.rubber_band.hide()
            self.capture_screenshot()

    def capture_screenshot(self):
        if not self.start_pos.isNull() and not self.end_pos.isNull():
            rect = QRect(self.start_pos, self.end_pos).normalized()
            screenshot = self.original_pixmap.copy(rect)

            # Save the image with specified quality
            screenshot.save("screenshot.webp", "webp", 70)

            self.close()

설명

  1. Overlay 클래스
  • Overlay 클래스는 전체 화면을 덮는 창을 생성하며, 딤 처리된 스크린샷 이미지를 표시합니다.
  • 사용자가 마우스로 드래그하여 선택한 영역을 QRubberBand를 사용하여 표시합니다.
  • 사용자가 영역을 선택하고 마우스를 놓으면 capture_screenshot 메서드가 호출되어 선택한 영역의 이미지를 webp 형식으로 70% 품질로 저장합니다.

전체 코드

import sys
from PyQt5.QtWidgets import QApplication, QMainWindow, QPushButton, QVBoxLayout, QWidget, QLabel, QRubberBand
from PyQt5.QtGui import QPixmap, QScreen, QPainter, QColor, QImageWriter
from PyQt5.QtCore import Qt, QRect, QPoint,QSize

class Overlay(QWidget):
    def __init__(self, original_pixmap, dimmed_pixmap, parent=None):
        super().__init__(parent)
        self.setWindowFlags(Qt.FramelessWindowHint | Qt.WindowStaysOnTopHint | Qt.Tool)
        self.setGeometry(QApplication.primaryScreen().geometry())
        self.original_pixmap = original_pixmap
        self.dimmed_pixmap = dimmed_pixmap

        # QLabel을 사용하여 스크린샷 이미지 표시
        self.label = QLabel(self)
        self.label.setPixmap(self.dimmed_pixmap)
        self.label.setGeometry(self.rect())

        self.rubber_band = QRubberBand(QRubberBand.Rectangle, self)
        self.start_pos = QPoint()
        self.end_pos = QPoint()

    def mousePressEvent(self, event):
        if event.button() == Qt.LeftButton:
            self.start_pos = event.pos()
            self.rubber_band.setGeometry(QRect(self.start_pos, QSize()))
            self.rubber_band.show()

    def mouseMoveEvent(self, event):
        if not self.start_pos.isNull():
            self.rubber_band.setGeometry(QRect(self.start_pos, event.pos()).normalized())

    def mouseReleaseEvent(self, event):
        if event.button() == Qt.LeftButton:
            self.end_pos = event.pos()
            self.rubber_band.hide()
            self.capture_screenshot()

    def capture_screenshot(self):
        if not self.start_pos.isNull() and not self.end_pos.isNull():
            rect = QRect(self.start_pos, self.end_pos).normalized()
            screenshot = self.original_pixmap.copy(rect)

            screenshot.save("screenshot.webp", "webp", 90)

            self.close()


class MainWindow(QMainWindow):
    def __init__(self):
        super().__init__()
        self.setWindowTitle("Screenshot Tool")
        self.setGeometry(100, 100, 800, 600)

        main_layout = QVBoxLayout()

        screenshot_button = QPushButton("Take Screenshot")
        screenshot_button.clicked.connect(self.show_overlay)

        main_layout.addWidget(screenshot_button)

        container = QWidget()
        container.setLayout(main_layout)
        self.setCentralWidget(container)

    def show_overlay(self):
        screen = QApplication.primaryScreen()
        original_screenshot = screen.grabWindow(0)

        dimmed_pixmap = QPixmap(original_screenshot.size())
        dimmed_pixmap.fill(Qt.transparent)
        painter = QPainter(dimmed_pixmap)
        painter.drawPixmap(0, 0, original_screenshot)
        painter.fillRect(original_screenshot.rect(), QColor(0, 0, 0, 128))  # 반투명 검은색 오버레이
        painter.end()

        self.overlay = Overlay(original_screenshot, dimmed_pixmap, self)
        self.overlay.showFullScreen()

if __name__ == "__main__":
    app = QApplication(sys.argv)
    window = MainWindow()
    window.show()
    sys.exit(app.exec_())

스크린샷

결론

이번 블로그 글에서는 PyQt를 사용하여 간단한 스크린샷 도구를 만드는 방법을 살펴보았습니다. 이 도구를 통해 사용자는 전체 화면을 스크린샷으로 찍고, 선택한 영역을 webp 형식으로 저장할 수 있습니다. PyQt의 강력한 기능을 활용하여 다양한 응용 프로그램을 개발할 수 있습니다. 이 예제를 바탕으로 여러분만의 스크린샷 도구를 만들어보세요!