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

2024-10-02 02:28:31 发布

您现在位置:Python中文网/ 问答频道 /正文

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

编辑: (我想在QtWebEngineWidgets中创建一个区域的屏幕截图,并将该区域作为一个对象。第二个问题是,我需要知道如何以两种不同的方式将该区域粘贴到QGraphicsView中:(从文件中)并将其显示为对象而不保存。2 QGraphicsView仅用于研究目的,它可能只是一个QGraphicsView,点击按钮1屏幕截图正在制作并粘贴为QGraphicsView的对象,点击按钮2-屏幕截图正在制作(保存为png并加载到QGraphicsView))

enter image description here

以下是我的代码:

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()

Tags: andfromimageimportselfinitdefscene
2条回答

QWebEngineView中的裁剪图像

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

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中显示图像

若要显示图像,则必须使用QGraphicsPixMap加载QPixmap的QGraphicsPixMap

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")加载图像,或使用pixmap_changed signal of RubberBandManager提供的QPixmap

为QGraphicsView设置场景

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))

相关问题 更多 >

    热门问题