繁体   English   中英

如何制作小部件的屏幕截图并将其粘贴到 QGraphicsView 中?

[英]How to make a screenshot of the widget and paste it into the QGraphicsView?

我在表单上有 2 个QGraphicsView和一个QWebEngineView小部件,我需要 *(单击按钮 1)* 对此QWebEngineView内的内容进行屏幕截图,并从原始QWebEngineView边框中定义一些挫折并将该屏幕截图保存为图像,同时将其保留为 object 并将此 object 粘贴到第一个QGraphicsView和 *(单击按钮 2)* 将保存的图像插入第二个QGraphicsView

编辑:(我想截取 QtWebEngineWidgets 内的区域并将该区域保留为 object。第二个问题我需要知道如何以两种不同的方式将该区域粘贴到 QGraphicsView 中:(来自文件)并将其显示为 object 而不保存。2 QGraphicsView 仅用于学习目的,它可能只是一个 QGraphicsView 并通过点击 button1 屏幕截图制作并粘贴为 object 到 QGraphicsView 并点击 button2 -screenshot 正在制作(保存为 png 并加载到 QGraphicsView))

在此处输入图像描述

这是我的代码:

import sys, os
from PyQt5.QtCore    import Qt
from PyQt5.QtGui     import QBrush, QPen, QScreen, QPixmap
from PyQt5.QtWidgets import QApplication, QStyleFactory, QMainWindow, QWidget, QVBoxLayout, QLabel
from PyQt5.QtWidgets import QGraphicsScene, QGraphicsView, QGraphicsItem, QPushButton
from pyqtgraph.Qt    import QtCore, QtGui
from PyQt5.QtWebEngineWidgets import QWebEngineView
from PyQt5.QtWidgets import QApplication, QDialog

class Geometry(QGraphicsView):
    def __init__(self):
        QGraphicsView.__init__(self)


class CentralPanel(QWidget):
    def __init__(self):
        QWidget.__init__(self)
        self.lblCoords = QLabel('MAP SELECTOR (object image):  ')
        self.lblCoords2 = QLabel('MAP SELECTOR (loaded from file image):  ')
        self.gvwShapes = Geometry()
        self.gvwShapes2 = Geometry()
        
        vbxDsply = QVBoxLayout()
        vbxDsply.addWidget(self.lblCoords)      # Capture coordinates of drawn line at window 1
        vbxDsply.addWidget(self.gvwShapes)      # add QGraphicsView #1
        
        vbxDsply.addWidget(self.lblCoords2)     # Capture coordinates of drawn line at window 2
        vbxDsply.addWidget(self.gvwShapes2)     # add QGraphicsView #2
        
        self.webEngineView = QWebEngineView()   # Add Google maps web window
        self.webEngineView.load(QtCore.QUrl("https://www.google.com/maps/@36.797966,-97.1413048,3464a,35y,0.92h/data=!3m1!1e3"))
        vbxDsply.addWidget(self.webEngineView)
        
        self.Button1 = QPushButton('Do screenshot of webEngineView save it and paste it into QGraphicsView2', self) # Button to load image to graphics view
        vbxDsply.addWidget(self.Button1)
        self.Button1.clicked.connect(self.button_screenshot)
        
        self.Button2 = QPushButton('Do screenshot of webEngineView and paste it into QGraphicsView1 ', self)
        vbxDsply.addWidget(self.Button2)
        self.Button2.clicked.connect(self.button_load_image)
        
        self.setLayout(vbxDsply)
        
        self.filename = "image.jpg"

    def button_screenshot(self):
        print('Screenshot is taken and saved as an image, Image loaded and inserted into the gvwShapes QGraphicsView1 ')
        app = QApplication(sys.argv)
        QScreen.grabWindow(app.primaryScreen(), QApplication.desktop().winId()).save(self.filename, 'png')

    def button_load_image(self):
        print('Screenshot is taken and inserted into the gvwShapes2 QGraphicsView2')
        
        # pix = QPixmap()
        # pix.load(self.filename)
        # pix = QPixmap(self.filename)
        # item = QGraphicsPixmapItem(pix)
        
        # scene = QGraphicsScence(self)
        # scene.addItem(item)
        # self.graphicsView.setScene(scene)
        
        scene = QtWidgets.QGraphicsScene(self)
        pixmap = QPixmap(self.filename)
        item = QtWidgets.QGraphicsPixmapItem(pixmap)
        scene.addItem(item)
        self.gvwShapes.setScene(scene)
        
        
        # scene = self.gvwShapes
        # self.image = QtGui.QPixmap(self.filename)
        # self.gvwShapes.add
        # scene.addItem(QtGui.QGraphicsPixmapItem(self.image))
        # self.view = self.QGraphicsView 
        # self.view.setScene(self.image)
        # self.view.show()
        
        
class MainWindow(QMainWindow):
    def __init__(self):
        QMainWindow.__init__(self)
        self.setGeometry(200, 50, 700, 900) 
        self.setWindowTitle('MAP Selector REV01')
        self.setStyle(QStyleFactory.create('Cleanlooks'))
        self.CenterPane = CentralPanel()
        self.setCentralWidget(self.CenterPane)




# Catching exceptions and running a main loop
#
import traceback
def except_hook(exc_type, exc_value, exc_tb):
    tb = "".join(traceback.format_exception(exc_type, exc_value, exc_tb))
    print("error cached")
    print("error message:\n", tb)

if __name__ == "__main__":
    MainEventThred = QApplication([])
    os.environ["QTWEBENGINE_CHROMIUM_FLAGS"] = "--enable-logging --log-level=3"
    sys.excepthook = except_hook
    MainApp = MainWindow()
    MainApp.show()
    MainEventThred.exec()

为您的 QGraphicsViews 设置一个场景。

self.gvwShapes = Geometry()
self.gvwShapes2 = Geometry()
self.gvwShapes.setScene(QGraphicsScene())
self.gvwShapes2.setScene(QGraphicsScene())

使用QWidget.grab()将其渲染为 QPixmap 并使用QGraphicsScene.addPixmap()将其添加到场景中。 您可以使用 QRect 指定区域。

def button_screenshot(self):
    pixmap = self.webEngineView.grab(QRect(180, 100, 300, 280))
    pixmap.save(self.filename)
    self.gvwShapes2.scene().addPixmap(pixmap)

def button_load_image(self):
    self.gvwShapes.scene().addPixmap(QPixmap(self.filename))

在 QWebEngineView 中裁剪图像

如果要实现 QWebEngineView 屏幕截图的裁剪,则必须使用 QWebEngineView 的 focusProxy () 上的 QRubberBand(它是呈现 web 页面并接收显示视图后创建的鼠标事件的小部件)

from functools import cached_property
import sys

from PyQt5.QtCore import pyqtSignal, QEvent, QObject, QPoint, QRect, QSize, QUrl
from PyQt5.QtGui import QPixmap
from PyQt5.QtWidgets import QApplication, QLabel, QRubberBand
from PyQt5.QtWebEngineWidgets import QWebEngineView


class RubberBandManager(QObject):
    pixmap_changed = pyqtSignal(QPixmap, name="pixmapChanged")

    def __init__(self, widget):
        super().__init__(widget)
        self._origin = QPoint()
        self._widget = widget

        self.widget.installEventFilter(self)

    @property
    def widget(self):
        return self._widget

    @cached_property
    def rubberband(self):
        return QRubberBand(QRubberBand.Rectangle, self.widget)

    def eventFilter(self, source, event):
        if self.widget is source:
            if event.type() == QEvent.MouseButtonPress:
                self._origin = event.pos()
                self.rubberband.setGeometry(QRect(self._origin, QSize()))
                self.rubberband.show()
            elif event.type() == QEvent.MouseMove:
                self.rubberband.setGeometry(
                    QRect(self._origin, event.pos()).normalized()
                )
            elif event.type() == QEvent.MouseButtonRelease:
                rect = self.rubberband.geometry()
                pixmap = self.widget.grab(rect)
                self.pixmap_changed.emit(pixmap)
                self.rubberband.hide()
        return super().eventFilter(source, event)


if __name__ == "__main__":
    app = QApplication(sys.argv)
    view = QWebEngineView()
    view.load(
        QUrl(
            "https://www.google.com/maps/@36.797966,-97.1413048,3464a,35y,0.92h/data=!3m1!1e3"
        )
    )
    view.show()
    rubberband_manager = RubberBandManager(view.focusProxy())

    label = QLabel()
    label.hide()

    def on_pixmap_changed(pixmap):
        label.setPixmap(pixmap)
        label.adjustSize()
        label.show()

    rubberband_manager.pixmap_changed.connect(on_pixmap_changed)

    ret = app.exec()
    sys.exit(ret)

在 QGraphicsView 中显示图像

要显示图像,您必须在加载 QPixmap 的位置使用 QGraphicsPixmapItem。

import sys

from PyQt5.QtCore import Qt
from PyQt5.QtGui import QPixmap, QPainter, QPalette
from PyQt5.QtWidgets import (
    QApplication,
    QGraphicsView,
    QGraphicsScene,
    QGraphicsPixmapItem,
)


class ImageViewer(QGraphicsView):
    def __init__(self, parent=None):
        super().__init__(parent)
        self.setRenderHints(QPainter.Antialiasing | QPainter.SmoothPixmapTransform)
        self.setAlignment(Qt.AlignCenter)
        self.setBackgroundRole(QPalette.Dark)

        scene = QGraphicsScene()
        self.setScene(scene)

        self._pixmap_item = QGraphicsPixmapItem()
        scene.addItem(self._pixmap_item)

    def load_pixmap(self, pixmap):
        self._pixmap_item.setPixmap(pixmap)
        self.fitToWindow()

    def fitToWindow(self):
        self.fitInView(self.sceneRect(), Qt.KeepAspectRatio)

    def resizeEvent(self, event):
        super().resizeEvent(event)
        self.fitToWindow()


if __name__ == "__main__":
    app = QApplication(sys.argv)

    view = ImageViewer()
    view.resize(640, 480)
    view.show()

    pixmap = QPixmap("image.jpg")
    view.load_pixmap(pixmap)

    ret = app.exec()
    sys.exit(ret)

前面的小部件用于从文件加载图像: pixmap = QPixmap("/path/of/image")或使用RubberBandManager的 pixmap_changed 信号提供的 QPixmap。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM