我试图在代码中替换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_())
这里的主要问题是用户点击像素图并对其进行处理的映射。
我希望有人可以提供帮助
预先感谢
正如错误所言。您从没有QLabel
属性/功能的itemAt
继承。参见:https://doc.qt.io/qt-5/qlabel.html。您可以尝试使用属性pos
和size
编写自己的比较。