将QGraphicsView替换为Qlabel [关闭]

问题描述 投票:2回答:1

我试图在代码中替换QGraphicsViews并改用Qlabels,因为我在处理QGraphicsViews时遇到很多困难。但是,当我这样做时,我遇到了很多问题,因为QGraphicsViews有其自己的方法,该方法并未为Qlabels实现。

这是QGraphicsViews的原始代码:

from PyQt5 import QtCore, QtGui, QtWidgets
import os
import sys

current_dir = os.path.dirname(os.path.realpath(__file__))
point_filename = os.path.join(current_dir, "Lastout.png")

class GraphicsView(QtWidgets.QGraphicsView):
    def __init__(self, parent=None):
        super().__init__(QtWidgets.QGraphicsScene(), parent)
        self.pixmap_item = self.scene().addPixmap(QtGui.QPixmap())
        self.pixmap_item.setShapeMode(QtWidgets.QGraphicsPixmapItem.BoundingRectShape)

        self.setAlignment(QtCore.Qt.AlignCenter)
        self.setHorizontalScrollBarPolicy(QtCore.Qt.ScrollBarAlwaysOff)
        self.setVerticalScrollBarPolicy(QtCore.Qt.ScrollBarAlwaysOff)

    def set_image(self, pixmap):
        self.pixmap_item.setPixmap(pixmap)
        #The pixmap is scaled to a rectangle as small as possible outside size, preserving the aspect ratio.
        self.fitInView(self.pixmap_item, QtCore.Qt.KeepAspectRatio)
        self.setSceneRect(self.scene().sceneRect())



class CropView(GraphicsView):
    Changed_view = QtCore.pyqtSignal(QtGui.QPixmap)

    def __init__(self, parent=None):
        super().__init__(parent)
        self.point_items = []
        self.crosshair = QtGui.QPixmap(point_filename)

    def mousePressEvent(self, event):
        if not self.pixmap_item.pixmap().isNull():
            if not self.itemAt(event.pos()) in self.point_items:
                scenePos = self.mapToScene(event.pos())
                if len(self.point_items) == 4:
                    while self.point_items:
                        self.scene().removeItem(self.point_items.pop())
                if self.pixmap_item.sceneBoundingRect().contains(scenePos):
                    point_item = self.scene().addPixmap(self.crosshair)
                    point_item.setPos(scenePos)
                    point_item.setFlag(point_item.ItemIgnoresTransformations)
                    point_item.setFlag(point_item.ItemIsMovable)
                    point_item.setOffset(-self.crosshair.rect().center())
                    self.point_items.append(point_item)
                    if len(self.point_items) == 4:
                        self.crop()
        super().mousePressEvent(event)

    def mouseMoveEvent(self, event):
        super().mouseMoveEvent(event)
        if len(self.point_items) == 4 and self.itemAt(event.pos()) in self.point_items:
            # update the rectangle if the points have been moved
            self.crop()

    def crop(self):
        points = []
        for point_item in self.point_items:
            points.append(self.pixmap_item.mapFromScene(point_item.pos()))

        # get the width and height based on the 4 points:
        # I'm assuming that the points are always in this order:
        # top-left, top-right, bottom-right, bottom-left
        # so we get the width from the longest two top and bottom lines
        # and the height from the longest left and right lines
        width = max(QtCore.QLineF(points[0], points[1]).length(), QtCore.QLineF(points[2], points[3]).length())
        height = max(QtCore.QLineF(points[1], points[2]).length(), QtCore.QLineF(points[3], points[0]).length())

        sourcePolygon = QtGui.QPolygonF(points)
        source = self.pixmap_item.pixmap()
        pixmap = QtGui.QPixmap(width, height)

        transform = QtGui.QTransform()
        rect = pixmap.rect()
        # this is the target used for the transformation
        targetPolygon = QtGui.QPolygonF([rect.topLeft(), rect.topRight(), rect.bottomRight(), rect.bottomLeft()])
        # quadToQuad is a static that sets the matrix of a transform based on two
        # four-sided polygons
        QtGui.QTransform.quadToQuad(sourcePolygon, targetPolygon, transform)

        painter = QtGui.QPainter(pixmap)
        # smooth pixmap transform is required for better results
        painter.setRenderHints(painter.SmoothPixmapTransform)
        painter.setTransform(transform)
        painter.drawPixmap(QtCore.QPoint(), source)
        painter.end()

        #Change the image to grayScale 
        Q_image = QtGui.QPixmap.toImage(pixmap)
        grayscale = Q_image.convertToFormat(QtGui.QImage.Format_Grayscale8)
        pixmap = QtGui.QPixmap.fromImage(grayscale)
        pixmap.save('output.png')
        self.Changed_view.emit(pixmap)


class MainWindow(QtWidgets.QMainWindow):
    def __init__(self, parent=None):
        super().__init__(parent)
        self.setFixedSize(1200, 700)

        self.left_view = CropView()
        self.rigth_view = GraphicsView()

        self.left_view.Changed_view.connect(self.rigth_view.set_image)


        self.setWindowTitle("Saudi License Plate Recognation System")
        icon = QtGui.QIcon()
        icon.addPixmap(QtGui.QPixmap("project pic/images LPR icon.png"), QtGui.QIcon.Normal, QtGui.QIcon.Off)
        self.setWindowIcon(icon)

        button = QtWidgets.QPushButton(self.tr("Browse Image"))
        button.setStyleSheet("background-color: rgb(140, 210, 211);")
        #button.setStyleSheet("background-color: rgb(0, 100, 100);")
        button.setFixedSize(230, 60)
        font = QtGui.QFont()
        font.setFamily("Microsoft YaHei UI")
        font.setPointSize(11)
        font.setBold(True)
        font.setWeight(75)
        button.setFont(font)
        button.setCursor(QtGui.QCursor(QtCore.Qt.PointingHandCursor))
        button.clicked.connect(self.load_image)


        central_widget = QtWidgets.QWidget()
        self.setCentralWidget(central_widget)
        lay = QtWidgets.QGridLayout(central_widget)
        lay.addWidget(self.left_view, 0, 0)
        lay.addWidget(self.rigth_view, 0, 1)
        lay.addWidget(button, 1, 0, 1, 2, alignment=QtCore.Qt.AlignHCenter)


    def load_image(self):
        fileName, _ = QtWidgets.QFileDialog.getOpenFileName(
            None, "Select Image", "", "Image Files (*.png *.jpg *jpeg *.bmp)"
        )
        if fileName:
            pixmap = QtGui.QPixmap(fileName)
            self.left_view.set_image(pixmap)


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

这是我尝试使用QLabels修改的代码:

from PyQt5 import QtCore, QtGui, QtWidgets
import os
import sys

current_dir = os.path.dirname(os.path.realpath(__file__))
point_filename = os.path.join(current_dir, "pointer.png")

class First_View(QtWidgets.QLabel):

    def __init__(self, parent=None):
        super().__init__(parent)
        self.setGeometry(20, 60, 600, 500)
        self.setMinimumSize(600, 500)
        self.setMaximumSize(600, 500)

        self.setFrameShape(QtWidgets.QFrame.StyledPanel)
        self.setFrameShadow(QtWidgets.QFrame.Plain)
        self.setLineWidth(1)
        self.setMidLineWidth(0)
        self.setText("")
        self.setScaledContents(False)
        self.setAlignment(QtCore.Qt.AlignCenter)

        self.origin = None
        self.point_items = []
        self.crosshair = QtGui.QPixmap(point_filename)

    def mousePressEvent(self, event):
        if not self.pixmap().isNull():
            if not event.pos() in self.point_items:
                scenePos = event.pos()
                if len(self.point_items) == 4:
                    while self.point_items:
                        self.pixmap.removeItem(self.point_items.pop())
                #Erorrs Starts form here
                if self.pixmap.contains(scenePos):
                    point_item = self.update(self.crosshair)
                    point_item.setPos(scenePos)
                    point_item.setFlag(point_item.ItemIgnoresTransformations)
                    point_item.setFlag(point_item.ItemIsMovable)
                    point_item.setOffset(-self.crosshair.rect().center())
                    self.point_items.append(point_item)
                    if len(self.point_items) == 4:
                        self.crop()
        super().mousePressEvent(event)

    def mouseMoveEvent(self, event):
        super().mouseMoveEvent(event)
        if len(self.point_items) == 4 and event.pos() in self.point_items:
            # update the rectangle if the points have been moved
            self.crop()

    def crop(self):
        points = []
        for point_item in self.point_items:
            points.append(self.pixmap_item.mapFromScene(point_item.pos()))


        width = max(QtCore.QLineF(points[0], points[1]).length(), QtCore.QLineF(points[2], points[3]).length())
        height = max(QtCore.QLineF(points[1], points[2]).length(), QtCore.QLineF(points[3], points[0]).length())

        sourcePolygon = QtGui.QPolygonF(points)
        source = self.pixmap_item.pixmap()
        pixmap = QtGui.QPixmap(width, height)

        transform = QtGui.QTransform()
        rect = pixmap.rect()
        # this is the target used for the transformation
        targetPolygon = QtGui.QPolygonF([rect.topLeft(), rect.topRight(), rect.bottomRight(), rect.bottomLeft()])
        # quadToQuad is a static that sets the matrix of a transform based on two
        # four-sided polygons
        QtGui.QTransform.quadToQuad(sourcePolygon, targetPolygon, transform)

        painter = QtGui.QPainter(pixmap)
        # smooth pixmap transform is required for better results
        painter.setRenderHints(painter.SmoothPixmapTransform)
        painter.setTransform(transform)
        painter.drawPixmap(QtCore.QPoint(), source)
        painter.end()

        #Change the image to grayScale 
        Q_image = QtGui.QPixmap.toImage(pixmap)
        grayscale = Q_image.convertToFormat(QtGui.QImage.Format_Grayscale8)
        pixmap = QtGui.QPixmap.fromImage(grayscale)
        Second_View.set_image(pixmap)

class Second_View(QtWidgets.QLabel):
    def __init__(self, parent=None):
        super().__init__(parent)
        self.setGeometry(680, 60, 600, 500)
        self.setMinimumSize(600, 500)
        self.setMaximumSize(600, 500)  
        self.setFrameShape(QtWidgets.QFrame.StyledPanel)
        self.setFrameShadow(QtWidgets.QFrame.Plain)
        self.setLineWidth(1)
        self.setMidLineWidth(0)
        self.setText("")
        self.setScaledContents(False)
        self.setAlignment(QtCore.Qt.AlignCenter)


    def set_image(self, pixmap):
        pixmap = pixmap.scaled(self.width(), self.height(), QtCore.Qt.KeepAspectRatio) # Scale pixmap
        self.setPixmap(pixmap)


class Ui_MainWindow(object):
    def setupUi(self, MainWindow):
        MainWindow.setObjectName("MainWindow")
        MainWindow.resize(1300, 800)
        MainWindow.setMinimumSize(QtCore.QSize(1300, 800))
        MainWindow.setMaximumSize(QtCore.QSize(1300, 800))
        icon = QtGui.QIcon()
        icon.addPixmap(QtGui.QPixmap("icon.png"), QtGui.QIcon.Normal, QtGui.QIcon.Off)
        MainWindow.setWindowIcon(icon)
        self.centralwidget = QtWidgets.QWidget(MainWindow)
        self.centralwidget.setObjectName("centralwidget")

        self.button = QtWidgets.QPushButton(self.centralwidget)
        self.button.setGeometry(QtCore.QRect(20, 620, 200, 60))
        self.button.setMinimumSize(QtCore.QSize(200, 60))
        self.button.setMaximumSize(QtCore.QSize(200, 60))
        font = QtGui.QFont()
        font.setFamily("Microsoft YaHei UI")
        font.setPointSize(11)
        font.setBold(True)
        font.setWeight(75)
        self.button.setFont(font)
        self.button.setCheckable(True)
        self.button.setObjectName("button")   
        self.line = QtWidgets.QFrame(self.centralwidget)
        self.line.setGeometry(QtCore.QRect(640, -10, 20, 811))
        self.line.setFrameShadow(QtWidgets.QFrame.Raised)
        self.line.setLineWidth(1)
        self.line.setFrameShape(QtWidgets.QFrame.VLine)
        self.line.setObjectName("line")

        MainWindow.setCentralWidget(self.centralwidget)
        self.menubar = QtWidgets.QMenuBar(MainWindow)
        self.menubar.setGeometry(QtCore.QRect(0, 0, 1300, 31))
        self.menubar.setObjectName("menubar")
        self.menuView = QtWidgets.QMenu(self.menubar)
        self.menuView.setLayoutDirection(QtCore.Qt.LeftToRight)
        self.menuView.setObjectName("menuView")
        self.menuHelp = QtWidgets.QMenu(self.menubar)
        self.menuHelp.setObjectName("menuHelp")
        MainWindow.setMenuBar(self.menubar)
        self.statusbar = QtWidgets.QStatusBar(MainWindow)
        self.statusbar.setObjectName("statusbar")
        MainWindow.setStatusBar(self.statusbar)
        self.menubar.addAction(self.menuView.menuAction())
        self.menubar.addAction(self.menuHelp.menuAction())
        self.retranslateUi(MainWindow)
        QtCore.QMetaObject.connectSlotsByName(MainWindow)

    def retranslateUi(self, MainWindow):
        _translate = QtCore.QCoreApplication.translate
        MainWindow.setWindowTitle(_translate("MainWindow", "Image processing"))
        self.button.setText(_translate("MainWindow", "Select Image"))
        self.menuView.setTitle(_translate("MainWindow", "View"))
        self.menuHelp.setTitle(_translate("MainWindow", "Help"))

class Views(QtWidgets.QMainWindow, Ui_MainWindow):
    def __init__(self, parent=None):
        super().__init__(parent)
        self.setupUi(self)

        self.First_view_label = First_View(self)
        self.Second_view_label = Second_View(self) 

       # self.left_view.Changed_view.connect(self.rigth_view.set_image)
        self.button.clicked.connect(self.load_image)


    def load_image(self):
        fileName, _ = QtWidgets.QFileDialog.getOpenFileName(
            None, "Select Image", "", "Image Files (*.png *.jpg *jpeg *.bmp)"
        )
        if fileName:
            pixmap = QtGui.QPixmap(fileName)
            pixmap = pixmap.scaled(self.First_view_label.width(), self.First_view_label.height(), QtCore.Qt.KeepAspectRatio) # Scale pixmap
            self.First_view_label.setPixmap(pixmap) # Set the pixmap onto the label
            self.First_view_label.setAlignment(QtCore.Qt.AlignCenter) # Align the label to center                    

if __name__ == "__main__": 
    app = QtWidgets.QApplication(sys.argv)
    w = Views()
    w.show()
    sys.exit(app.exec_())

这里的主要问题是用户点击像素图并对其进行处理的映射。

我希望有人可以提供帮助

预先感谢

python python-3.x pyqt pyqt5 qgraphicsview
1个回答
-1
投票

正如错误所言。您从没有QLabel属性/功能的itemAt继承。参见:https://doc.qt.io/qt-5/qlabel.html。您可以尝试使用属性possize编写自己的比较。

© www.soinside.com 2019 - 2024. All rights reserved.