【问题标题】:Pyqt take screenshot of certain screen areaPyqt 截取特定屏幕区域
【发布时间】:2016-04-06 16:35:40
【问题描述】:

我有这个用 pyqt 编写的应用程序。您可以在http://www.pasteall.org/62739/python查看源代码它会截取桌面的屏幕截图。我想知道的是如何让它也像窗口的截图工具一样拍摄屏幕上某个区域的屏幕截图(http://sjcblogs.sanjac.edu/its/files/2011/09/Snipping-Tool-selection-types1.jpg 和 gilsmethod.wpengine.netdna-cdn.com/images/snipping-tool-windows -73.png)。这个怎么写?

提前谢谢你!

【问题讨论】:

标签: python pyqt screenshot area


【解决方案1】:

你应该使用

img = QPixmap.grabWindow(QApplication.desktop().winId(), x, y, width, height)

pyqt 发行版有一个非常好的 python 示例,用于使用 pyqt 进行截图。该示例的 C++ 代码很容易转换为 Python,位于 http://doc.qt.io/qt-4.8/qt-desktop-screenshot-example.html

【讨论】:

    【解决方案2】:

    安装以下软件包:

    pip install pillow opencv-python pyside2
    

    运行以下代码:

    import sys
    
    from PySide2.QtCore import *
    from PySide2.QtGui import *
    from PySide2.QtWidgets import *
    
    import numpy as np
    import cv2
    from PIL import ImageGrab
    
    class Ui_MainWindow(object):
        def setupUi(self, MainWindow):
            if not MainWindow.objectName():
                MainWindow.setObjectName(u"MainWindow")
            MainWindow.resize(1000, 1000)
            sizePolicy = QSizePolicy(QSizePolicy.Maximum, QSizePolicy.Maximum)
            sizePolicy.setHorizontalStretch(0)
            sizePolicy.setVerticalStretch(0)
            sizePolicy.setHeightForWidth(MainWindow.sizePolicy().hasHeightForWidth())
            MainWindow.setSizePolicy(sizePolicy)
            MainWindow.setMinimumSize(QSize(1000, 1000))
            MainWindow.setMaximumSize(QSize(16777215, 16777215))
            MainWindow.setTabShape(QTabWidget.Rounded)
            self.centralwidget = QWidget(MainWindow)
            self.centralwidget.setObjectName(u"centralwidget")
            sizePolicy1 = QSizePolicy(QSizePolicy.Preferred, QSizePolicy.Preferred)
            sizePolicy1.setHorizontalStretch(0)
            sizePolicy1.setVerticalStretch(0)
            sizePolicy1.setHeightForWidth(self.centralwidget.sizePolicy().hasHeightForWidth())
            self.centralwidget.setSizePolicy(sizePolicy1)
            self.centralwidget.setMinimumSize(QSize(1000, 1000))
            self.gridLayout = QGridLayout(self.centralwidget)
            self.gridLayout.setObjectName(u"gridLayout")
            self.pushButton_area = QPushButton(self.centralwidget)
            self.pushButton_area.setObjectName(u"pushButton_area")
            self.pushButton_area.setMinimumSize(QSize(800, 0))
    
            self.gridLayout.addWidget(self.pushButton_area, 0, 0, 1, 1)
    
            self.label = QLabel(self.centralwidget)
            self.label.setObjectName(u"label")
            sizePolicy2 = QSizePolicy(QSizePolicy.Expanding, QSizePolicy.Expanding)
            sizePolicy2.setHorizontalStretch(0)
            sizePolicy2.setVerticalStretch(0)
            sizePolicy2.setHeightForWidth(self.label.sizePolicy().hasHeightForWidth())
            self.label.setSizePolicy(sizePolicy2)
            self.label.setMinimumSize(QSize(800, 800))
            self.label.setMaximumSize(QSize(4096, 4096))
    
            self.gridLayout.addWidget(self.label, 2, 0, 2, 1)
    
            self.pushButton_full = QPushButton(self.centralwidget)
            self.pushButton_full.setObjectName(u"pushButton_full")
            self.pushButton_full.setMinimumSize(QSize(800, 0))
    
            self.gridLayout.addWidget(self.pushButton_full, 1, 0, 1, 1)
    
            MainWindow.setCentralWidget(self.centralwidget)
    
            self.retranslateUi(MainWindow)
    
            QMetaObject.connectSlotsByName(MainWindow)
    
        def retranslateUi(self, MainWindow):
            MainWindow.setWindowTitle(QCoreApplication.translate("MainWindow", u"Snipping Tool", None))
            MainWindow.setAccessibleName(QCoreApplication.translate("MainWindow", u"Snipping Tool", None))
            self.pushButton_area.setText(QCoreApplication.translate("MainWindow", u"Select Area", None))
            self.pushButton_full.setText(QCoreApplication.translate("MainWindow", u"Fullscreen", None))
    
    # Refer to https://github.com/harupy/snipping-tool
    class SnippingWidget(QWidget):
        is_snipping = False
    
        def __init__(self, parent=None, app=None):
            super(SnippingWidget, self).__init__()
            self.parent = parent
            self.setWindowFlags(Qt.WindowStaysOnTopHint)
    
            self.screen = app.primaryScreen()
            self.setGeometry(0, 0, self.screen.size().width(), self.screen.size().height())
            self.begin = QPoint()
            self.end = QPoint()
            self.onSnippingCompleted = None
    
        def fullscreen(self):
            img = ImageGrab.grab(bbox=(0, 0, self.screen.size().width(), self.screen.size().height()))
    
            try:
                img = cv2.cvtColor(np.array(img), cv2.COLOR_RGB2BGR)
            except:
                img = None
                
            if self.onSnippingCompleted is not None:
                self.onSnippingCompleted(img)
    
        def start(self):
            SnippingWidget.is_snipping = True
            self.setWindowOpacity(0.3)
            QApplication.setOverrideCursor(QCursor(Qt.CrossCursor))
            self.show()
    
        def paintEvent(self, event):
            if SnippingWidget.is_snipping:
                brush_color = (128, 128, 255, 100)
                lw = 3
                opacity = 0.3
            else:
                self.begin = QPoint()
                self.end = QPoint()
                brush_color = (0, 0, 0, 0)
                lw = 0
                opacity = 0
    
            self.setWindowOpacity(opacity)
            qp = QPainter(self)
            qp.setPen(QPen(QColor('black'), lw))
            qp.setBrush(QColor(*brush_color))
            rect = QRectF(self.begin, self.end)
            qp.drawRect(rect)
    
        def mousePressEvent(self, event):
            self.begin = event.pos()
            self.end = self.begin
            self.update()
    
        def mouseMoveEvent(self, event):
            self.end = event.pos()
            self.update()
    
        def mouseReleaseEvent(self, event):
            SnippingWidget.is_snipping = False
            QApplication.restoreOverrideCursor()
            x1 = min(self.begin.x(), self.end.x())
            y1 = min(self.begin.y(), self.end.y())
            x2 = max(self.begin.x(), self.end.x())
            y2 = max(self.begin.y(), self.end.y())
    
            self.repaint()
            QApplication.processEvents()
            img = ImageGrab.grab(bbox=(x1, y1, x2, y2))
    
            try:
                img = cv2.cvtColor(np.array(img), cv2.COLOR_RGB2BGR)
            except:
                img = None
                
            if self.onSnippingCompleted is not None:
                self.onSnippingCompleted(img)
    
            self.close()
    
    class MainWindow(QMainWindow):
        useQThread = True
    
        def __init__(self):
            super(MainWindow, self).__init__()
            self.ui = Ui_MainWindow()
            self.ui.setupUi(self)
            self.setAcceptDrops(True)
    
            self.snippingWidget = SnippingWidget(app=QApplication.instance())
            self.snippingWidget.onSnippingCompleted = self.onSnippingCompleted
            self.ui.pushButton_area.clicked.connect(self.snipArea)
            self.ui.pushButton_full.clicked.connect(self.snipFull)
    
            self._pixmap = None
    
        def onSnippingCompleted(self, frame):
            self.setWindowState(Qt.WindowActive)
            if frame is None:
                return 
    
            image = QImage(frame, frame.shape[1], frame.shape[0], frame.strides[0], QImage.Format_RGB888)
            pixmap = QPixmap.fromImage(image)
            self._pixmap = self.resizeImage(pixmap)
            self.ui.label.setPixmap(self._pixmap)
    
        def snipArea(self):
            self.setWindowState(Qt.WindowMinimized)
            self.snippingWidget.start()    
    
        def snipFull(self):
            self.setWindowState(Qt.WindowMinimized)
            self.snippingWidget.fullscreen()    
    
        def dragEnterEvent(self, event):
            event.acceptProposedAction()
    
        def dropEvent(self, event):
            urls = event.mimeData().urls()
            filename = urls[0].toLocalFile()
            self.loadFile(filename)
            self.decodeFile(filename)
            event.acceptProposedAction()
    
        def resizeImage(self, pixmap):
            lwidth = self.ui.label.width()
            pwidth = pixmap.width()
            lheight = self.ui.label.height()
            pheight = pixmap.height()
    
            wratio = pwidth * 1.0 / lwidth
            hratio = pheight * 1.0 / lheight
    
            if pwidth > lwidth or pheight > lheight:
                if wratio > hratio:
                    lheight = pheight / wratio
                else:
                    lwidth = pwidth / hratio
    
                scaled_pixmap = pixmap.scaled(lwidth, lheight)
                return scaled_pixmap
            else:
                return pixmap
    
        def showMessageBox(self, title, content):
            msgBox = QMessageBox()
            msgBox.setWindowTitle(title)
            msgBox.setText(content)
            msgBox.exec_()
    
        def closeEvent(self, event):
        
            msg = "Close the app?"
            reply = QMessageBox.question(self, 'Message', 
                            msg, QMessageBox.Yes, QMessageBox.No)
    
            if reply == QMessageBox.Yes:
                event.accept()
            else:
                event.ignore()
    
    def main():
        app = QApplication(sys.argv)
        window = MainWindow()
        window.show()
        sys.exit(app.exec_())
    
    if __name__ == '__main__':
        main()
    

    【讨论】:

      猜你喜欢
      • 2015-03-23
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2021-12-27
      • 2012-01-31
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多