使用可拖动的QLabel进行裁剪

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

我正在尝试使用可拖动的QLabel裁剪图像。我的代码的基本思想是分割图像中的字符。

因此,用户将首先将包含三个字符的图像上载到程序。然后,他将通过选择适当的复选框来指定板的类型,是短板还是长板。根据该复选框,将向用户显示三个具有特定大小的框(QLabel),以便用户可以将每个框拖到上载图像中的角色上。一旦用户将框放置在字符上,他就可以单击Segment按钮以应用裁剪操作。最终结果将是裁剪后的角色的三幅图像。

我已经从程序界面和某些功能中完成了工作,但是,我面临着darg和裁剪功能的问题。我已经尝试过使用拖动框(QLabels)的不同方式,但是它对我不起作用。我真的不知道我的代码有什么问题:(。我正在使用python 3PyQt5

这是我的代码:

from PyQt5 import QtCore, QtGui, QtWidgets
from PyQt5.QtWidgets import QApplication, QLabel, QWidget
from PyQt5.QtGui import QDrag, QPixmap, QPainter, QCursor
from PyQt5.QtCore import QMimeData, Qt

boxes_items = []

#=========================================================================
class DraggableLabel(QLabel):

    def __init__(self, *args, **kwargs):
        super().__init__(*args, **kwargs)
        self.setAcceptDrops(True)


    def dragEnterEvent(self, event):
        event.accept()
        event.acceptProposedAction()

    def mousePressEvent(self, event):
        if event.button() == Qt.LeftButton:
            event.accept()
            self.setCursor(QtGui.QCursor(QtCore.Qt.CloseHandCursor))
            self.drag_start_position = event.pos()


    def mouseMoveEvent(self, event):
        if not (event.buttons() & Qt.LeftButton):
           return
        if (event.pos() - self.drag_start_position).manhattanLength() < QApplication.startDragDistance():
           return
        drag = QDrag(self)
        '''
        mimedata = QMimeData()
        #mimedata.setText(self.text())
        mimedata.setImageData(self.pixmap().toImage())
        drag.setMimeData(mimedata)
        pixmap = QPixmap(self.size())
        painter = QPainter(pixmap)
        painter.drawPixmap(self.rect(), self.grab())
        painter.end()
        drag.setPixmap(pixmap)
        '''

        drag.setHotSpot(event.pos())
        drag.exec_(Qt.CopyAction | Qt.MoveAction)

'''
class DropLabel(QLabel):
    def __init__(self, *args, **kwargs):
        QLabel.__init__(self, *args, **kwargs)
        self.setAcceptDrops(True)

    def dragEnterEvent(self, event):
        if event.mimeData().hasText():
            event.acceptProposedAction()

    def dropEvent(self, event):
        pos = event.pos()
        self.setCursor(QtGui.QCursor(QtCore.Qt.OpenHandCursor))
       # text = event.mimeData().text()
       # self.setText(text)
        event.acceptProposedAction()
'''

#==========================================================================
class Ui_Dialog(object):
    def setupUi(self, Dialog):
        Dialog.setObjectName("Dialog")
        Dialog.setEnabled(True)
        Dialog.resize(1050, 800)
        Dialog.setMinimumSize(QtCore.QSize(1050, 800))
        Dialog.setMaximumSize(QtCore.QSize(1050, 800))
        icon = QtGui.QIcon()
        icon.addPixmap(QtGui.QPixmap("../.designer/backup/project pic/images LPR icon.png"), QtGui.QIcon.Normal, QtGui.QIcon.Off)
        Dialog.setWindowIcon(icon)
        Dialog.setStyleSheet("background-color: rgb(217, 217, 217);\n"
"background-color: rgb(243, 243, 243);")
       # Dialog.setAcceptDrops(True)

        self.BrowesImageButton = QtWidgets.QPushButton(Dialog)
        self.BrowesImageButton.setGeometry(QtCore.QRect(820, 60, 200, 60))
        self.BrowesImageButton.setMinimumSize(QtCore.QSize(200, 60))
        self.BrowesImageButton.setMaximumSize(QtCore.QSize(200, 60))
        font = QtGui.QFont()
        font.setFamily("Microsoft YaHei UI")
        font.setPointSize(11)
        font.setBold(True)
        font.setWeight(75)

        self.BrowesImageButton.setFont(font)
        self.BrowesImageButton.setStyleSheet("")
        self.BrowesImageButton.setCheckable(True)
        self.BrowesImageButton.setObjectName("BrowesImageButton")
        self.groupBox = QtWidgets.QGroupBox(Dialog)
        self.groupBox.setGeometry(QtCore.QRect(820, 170, 211, 131))
        font = QtGui.QFont()
        font.setFamily("Microsoft YaHei")
        font.setPointSize(10)
        font.setBold(True)

        font.setWeight(75)
        self.groupBox.setFont(font)
        self.groupBox.setLayoutDirection(QtCore.Qt.LeftToRight)
        self.groupBox.setObjectName("groupBox")
        self.checkBox_Short = QtWidgets.QCheckBox(self.groupBox)
        self.checkBox_Short.setGeometry(QtCore.QRect(20, 40, 141, 23))
        font = QtGui.QFont()
        font.setFamily("Adobe Heiti Std R")
        font.setPointSize(10)

        self.checkBox_Short.setFont(font)
        self.checkBox_Short.setLayoutDirection(QtCore.Qt.LeftToRight)
        self.checkBox_Short.setObjectName("checkBox_Short")
        self.checkBox_Short.setEnabled(False)

        self.checkBox_Long = QtWidgets.QCheckBox(self.groupBox)
        self.checkBox_Long.setGeometry(QtCore.QRect(20, 80, 141, 23))
        font = QtGui.QFont()
        font.setFamily("Adobe Heiti Std R")
        font.setPointSize(10)

        self.checkBox_Long.setFont(font)
        self.checkBox_Long.setLayoutDirection(QtCore.Qt.LeftToRight)
        self.checkBox_Long.setObjectName("checkBox_Long")
        self.checkBox_Long.setEnabled(False)

        self.SegmentImageButton = QtWidgets.QPushButton(Dialog)
        self.SegmentImageButton.setGeometry(QtCore.QRect(830, 330, 200, 60))
        self.SegmentImageButton.setMinimumSize(QtCore.QSize(200, 60))
        self.SegmentImageButton.setMaximumSize(QtCore.QSize(200, 60))

        font = QtGui.QFont()
        font.setFamily("Microsoft YaHei UI")
        font.setPointSize(11)
        font.setBold(True)
        font.setWeight(75)
        self.SegmentImageButton.setFont(font)
        self.SegmentImageButton.setStyleSheet("")
        self.SegmentImageButton.setCheckable(True)
        self.SegmentImageButton.setObjectName("SegmentImageButton")
        self.SegmentImageButton.setEnabled(False)

        self.label = QtWidgets.QLabel(Dialog)
        self.label.setGeometry(QtCore.QRect(980, 470, 45, 45))
        self.label.setMinimumSize(QtCore.QSize(45, 45))
        self.label.setMaximumSize(QtCore.QSize(45, 45))
        self.label.setCursor(QtGui.QCursor(QtCore.Qt.OpenHandCursor))
        self.label.setMouseTracking(True)
        self.label.setAcceptDrops(True)
        self.label.setStyleSheet("border-color: rgb(238, 0, 0); border-width : 2.0px; border-style:inset;")
        self.label.setFrameShape(QtWidgets.QFrame.Box)
        self.label.setLineWidth(2)
        self.label.setText("")
        self.label.setObjectName("label")
        self.label.hide()

        '''
        self.graphicsView = QtWidgets.QGraphicsView(Dialog)
        self.graphicsView.setGeometry(QtCore.QRect(40, 40, 750, 500))
        self.graphicsView.setMinimumSize(QtCore.QSize(750, 500))
        self.graphicsView.setMaximumSize(QtCore.QSize(750, 500))
        self.graphicsView.setObjectName("graphicsView")
        '''
        self.UserImageLbl = QtWidgets.QLabel(Dialog)
        self.UserImageLbl.setGeometry(QtCore.QRect(40, 40, 750, 500))
        self.UserImageLbl.setMinimumSize(QtCore.QSize(750, 500))
        self.UserImageLbl.setMaximumSize(QtCore.QSize(750, 500))
        self.UserImageLbl.setFrameShape(QtWidgets.QFrame.StyledPanel)
        self.UserImageLbl.setFrameShadow(QtWidgets.QFrame.Plain)
        self.UserImageLbl.setLineWidth(1)
        self.UserImageLbl.setMidLineWidth(0)
        self.UserImageLbl.setText("")
        self.UserImageLbl.setScaledContents(False)
        self.UserImageLbl.setAlignment(QtCore.Qt.AlignCenter)
        self.UserImageLbl.setObjectName("UserImageLbl")



        self.label_2 = QtWidgets.QLabel(Dialog)
        self.label_2.setGeometry(QtCore.QRect(900, 470, 45, 45))
        self.label_2.setMinimumSize(QtCore.QSize(45, 45))
        self.label_2.setMaximumSize(QtCore.QSize(45, 45))
        self.label_2.setCursor(QtGui.QCursor(QtCore.Qt.OpenHandCursor))
        self.label_2.setMouseTracking(True)
        self.label_2.setAcceptDrops(True)
        self.label_2.setStyleSheet("border-color: rgb(238, 0, 0); border-width : 2.0px; border-style:inset;")
        self.label_2.setFrameShape(QtWidgets.QFrame.Box)
        self.label_2.setLineWidth(2)
        self.label_2.setText("")
        self.label_2.setObjectName("label_2")
        self.label_2.hide()

        self.label_3 = QtWidgets.QLabel(Dialog)
        self.label_3.setGeometry(QtCore.QRect(820, 470, 45, 45))
        self.label_3.setMinimumSize(QtCore.QSize(45, 45))
        self.label_3.setMaximumSize(QtCore.QSize(45, 45))
        self.label_3.setCursor(QtGui.QCursor(QtCore.Qt.OpenHandCursor))
        self.label_3.setMouseTracking(True)
        self.label_3.setAcceptDrops(True)
        self.label_3.setStyleSheet("border-color: rgb(238, 0, 0); border-width : 2.0px; border-style:inset;")
        self.label_3.setFrameShape(QtWidgets.QFrame.Box)
        self.label_3.setLineWidth(2)
        self.label_3.setText("")
        self.label_3.setObjectName("label_3")
        self.label_3.hide()

        self.retranslateUi(Dialog)
        QtCore.QMetaObject.connectSlotsByName(Dialog)

        #Add labels in boxes items list 

        boxes_items.append(self.label)
        boxes_items.append(self.label_2)
        boxes_items.append(self.label_3)



#=================================== Calling =======================

        self.BrowesImageButton.clicked.connect(self.setImage)
        self.checkBox_Short.stateChanged.connect(self.Change_the_Checkbox_Short_Function)
        self.checkBox_Long.stateChanged.connect(self.Change_the_Checkbox_Long_Function)

#=================================== Functions =========================

    def retranslateUi(self, Dialog):
        _translate = QtCore.QCoreApplication.translate
        Dialog.setWindowTitle(_translate("Dialog", "Cropping"))
        self.BrowesImageButton.setText(_translate("Dialog", "Select Image"))
        self.groupBox.setTitle(_translate("Dialog", "Choose Plate Type"))
        self.checkBox_Short.setText(_translate("Dialog", "Short Plate"))
        self.checkBox_Long.setText(_translate("Dialog", "Long Plate"))
        self.SegmentImageButton.setText(_translate("Dialog", "Segment Image"))
        self.label.setToolTip(_translate("Dialog", "Drage it on first charecter"))
        self.label_2.setToolTip(_translate("Dialog", "Drage it on second charecter"))
        self.label_3.setToolTip(_translate("Dialog", "Drage it on third charecter"))

#=================================================================================

    def setImage(self):
        fileName, _ = QtWidgets.QFileDialog.getOpenFileName(None, "Select Image", "", "Image Files (*.png *.jpg *jpeg *.bmp)") # Ask for file

        if fileName: # If the user gives a file
            pixmap = QtGui.QPixmap(fileName) # Setup pixmap with the provided image
            pixmap = pixmap.scaled(self.UserImageLbl.width(), self.UserImageLbl.height(), QtCore.Qt.KeepAspectRatio) # Scale pixmap
            self.UserImageLbl.setPixmap(pixmap) # Set the pixmap onto the label
            self.UserImageLbl.setAlignment(QtCore.Qt.AlignCenter) # Align the label to center
            #UserImageLbl = DropLabel()
            self.checkBox_Short.setEnabled(True)
            self.checkBox_Long.setEnabled(True)

#=====================================================================    
    def Change_the_Checkbox_Short_Function(self):
        if self.checkBox_Short.isChecked(): 
           self.checkBox_Long.setEnabled(False)
           self.SegmentImageButton.setEnabled(True)

           # Presenting 3 boxes 45x45 hear
           for box_item in boxes_items:
               #box_item.setDragEnabled(True) 
               box_item.setMinimumSize(QtCore.QSize(45, 45))
               box_item.setMaximumSize(QtCore.QSize(45, 45))
               box_item.show()
               box_item = DraggableLabel()  


        else:
           self.checkBox_Long.setEnabled(True)
           for box_item in boxes_items:
               box_item.hide()

#========================================================================       

    def Change_the_Checkbox_Long_Function(self):
        if self.checkBox_Long.isChecked(): 
           self.checkBox_Short.setEnabled(False)
           self.SegmentImageButton.setEnabled(True)

           # Presenting 3 boxes 40x40 hear
           for box_item in boxes_items:
              # box_item.setDragEnabled(True) 
               box_item.setMinimumSize(QtCore.QSize(40, 40))
               box_item.setMaximumSize(QtCore.QSize(40, 40))
               box_item.show()
               box_item = DraggableLabel()  

           #for box_item in Sboxes_items:    
               #DraggableLabel(box_item)  

        else:
           self.checkBox_Short.setEnabled(True)
           for box_item in boxes_items:
               box_item.hide()

#==========================================================================

if __name__ == "__main__":
    import sys
    app = QtWidgets.QApplication(sys.argv)
    Dialog = QtWidgets.QDialog()
    ui = Ui_Dialog()
    ui.setupUi(Dialog)
    Dialog.show()
    sys.exit(app.exec_())

我希望我能找到可以帮助我的人。提前致谢。

python python-3.x pyqt drag-and-drop pyqt5
1个回答
1
投票

我相信您对拖放的工作方式有些困惑,但是最重要的是,您不需要为实现的目标而进行“实际”拖放。

在本示例中,我添加了可拖动的框而不是标签,它们可以在图像矩形内自由移动。我必须对您的原始代码进行一些修改,因为这有点令人困惑,并且有些逻辑根本行不通。

class DraggableLabel(QLabel):

    def __init__(self, *args, **kwargs):
        super().__init__(*args, **kwargs)
        self.setStyleSheet("border-color: rgb(238, 0, 0); border-width : 2.0px; border-style:inset; background: transparent;")
        self.origin = None

    def setLimits(self, rect):
        self.limits = rect

    def mousePressEvent(self, event):
        if not self.origin:
            # update the origin point, we'll need that later
            self.origin = self.pos()
        if event.button() == Qt.LeftButton:
            self.mousePos = event.pos()

    def mouseMoveEvent(self, event):
        if event.buttons() == Qt.LeftButton:
            # move the box
            self.move(self.pos() + event.pos() - self.mousePos)

    def mouseReleaseEvent(self, event):
        if event.button() == Qt.LeftButton:
            # if the box is not within the image boundaries, move it
            # back to the original position
            if not self.limits.contains(self.geometry()):
                self.move(self.origin)


class Ui_Dialog(object):
    def setupUi(self, Dialog):
        Dialog.setObjectName("Dialog")
        Dialog.setEnabled(True)
        Dialog.resize(1050, 800)
        Dialog.setMinimumSize(QtCore.QSize(1050, 800))
        Dialog.setMaximumSize(QtCore.QSize(1050, 800))
        icon = QtGui.QIcon()
        icon.addPixmap(QtGui.QPixmap("../.designer/backup/project pic/images LPR icon.png"), QtGui.QIcon.Normal, QtGui.QIcon.Off)
        Dialog.setWindowIcon(icon)
        Dialog.setStyleSheet("background-color: rgb(217, 217, 217);\n"
"background-color: rgb(243, 243, 243);")
       # Dialog.setAcceptDrops(True)

        self.BrowesImageButton = QtWidgets.QPushButton(Dialog)
        self.BrowesImageButton.setGeometry(QtCore.QRect(820, 60, 200, 60))
        self.BrowesImageButton.setMinimumSize(QtCore.QSize(200, 60))
        self.BrowesImageButton.setMaximumSize(QtCore.QSize(200, 60))
        font = QtGui.QFont()
        font.setFamily("Microsoft YaHei UI")
        font.setPointSize(11)
        font.setBold(True)
        font.setWeight(75)

        self.BrowesImageButton.setFont(font)
        self.BrowesImageButton.setStyleSheet("")
        self.BrowesImageButton.setCheckable(True)
        self.BrowesImageButton.setObjectName("BrowesImageButton")
        self.groupBox = QtWidgets.QGroupBox(Dialog)
        self.groupBox.setGeometry(QtCore.QRect(820, 170, 211, 131))
        font = QtGui.QFont()
        font.setFamily("Microsoft YaHei")
        font.setPointSize(10)
        font.setBold(True)

        font.setWeight(75)
        self.groupBox.setFont(font)
        self.groupBox.setLayoutDirection(QtCore.Qt.LeftToRight)
        self.groupBox.setObjectName("groupBox")
        self.checkBox_Short = QtWidgets.QCheckBox(self.groupBox)
        self.checkBox_Short.setGeometry(QtCore.QRect(20, 40, 141, 23))
        font = QtGui.QFont()
        font.setFamily("Adobe Heiti Std R")
        font.setPointSize(10)

        self.checkBox_Short.setFont(font)
        self.checkBox_Short.setLayoutDirection(QtCore.Qt.LeftToRight)
        self.checkBox_Short.setObjectName("checkBox_Short")
        self.checkBox_Short.setEnabled(False)

        self.checkBox_Long = QtWidgets.QCheckBox(self.groupBox)
        self.checkBox_Long.setGeometry(QtCore.QRect(20, 80, 141, 23))
        font = QtGui.QFont()
        font.setFamily("Adobe Heiti Std R")
        font.setPointSize(10)

        self.checkBox_Long.setFont(font)
        self.checkBox_Long.setLayoutDirection(QtCore.Qt.LeftToRight)
        self.checkBox_Long.setObjectName("checkBox_Long")
        self.checkBox_Long.setEnabled(False)

        self.SegmentImageButton = QtWidgets.QPushButton(Dialog)
        self.SegmentImageButton.setGeometry(QtCore.QRect(830, 330, 200, 60))
        self.SegmentImageButton.setMinimumSize(QtCore.QSize(200, 60))
        self.SegmentImageButton.setMaximumSize(QtCore.QSize(200, 60))

        font = QtGui.QFont()
        font.setFamily("Microsoft YaHei UI")
        font.setPointSize(11)
        font.setBold(True)
        font.setWeight(75)
        self.SegmentImageButton.setFont(font)
        self.SegmentImageButton.setStyleSheet("")
        self.SegmentImageButton.setCheckable(True)
        self.SegmentImageButton.setObjectName("SegmentImageButton")
        self.SegmentImageButton.setEnabled(False)

        self.UserImageLbl = QtWidgets.QLabel(Dialog)
        self.UserImageLbl.setGeometry(QtCore.QRect(40, 40, 750, 500))
        self.UserImageLbl.setMinimumSize(QtCore.QSize(750, 500))
        self.UserImageLbl.setMaximumSize(QtCore.QSize(750, 500))
        self.UserImageLbl.setFrameShape(QtWidgets.QFrame.StyledPanel)
        self.UserImageLbl.setFrameShadow(QtWidgets.QFrame.Plain)
        self.UserImageLbl.setLineWidth(1)
        self.UserImageLbl.setMidLineWidth(0)
        self.UserImageLbl.setText("")
        self.UserImageLbl.setScaledContents(False)
        self.UserImageLbl.setAlignment(QtCore.Qt.AlignCenter)
        self.UserImageLbl.setObjectName("UserImageLbl")

        self.buttonGroup = QButtonGroup()
        self.buttonGroup.addButton(self.checkBox_Short)
        self.buttonGroup.addButton(self.checkBox_Long)

        self.label_1 = DraggableLabel(Dialog)
        self.label_2 = DraggableLabel(Dialog)
        self.label_3 = DraggableLabel(Dialog)

        self.label_1.move(820, 470)
        self.label_2.move(900, 470)
        self.label_3.move(980, 470)

        self.labels = [self.label_1, self.label_2, self.label_3]
        for label in self.labels:
            label.hide()
            label.raise_()

        self.BrowesImageButton.clicked.connect(self.setImage)
        self.checkBox_Long.toggled.connect(self.setBoxSizes)
        self.checkBox_Short.toggled.connect(self.setBoxSizes)

    def setImage(self):
        fileName, _ = QtWidgets.QFileDialog.getOpenFileName(None, "Select Image", "", "Image Files (*.png *.jpg *jpeg *.bmp)") # Ask for file

        if fileName: # If the user gives a file
            pixmap = QtGui.QPixmap(fileName) # Setup pixmap with the provided image
            pixmap = pixmap.scaled(self.UserImageLbl.width(), self.UserImageLbl.height(), QtCore.Qt.KeepAspectRatio) # Scale pixmap
            self.UserImageLbl.setPixmap(pixmap) # Set the pixmap onto the label
            self.UserImageLbl.setAlignment(QtCore.Qt.AlignCenter) # Align the label to center
            #UserImageLbl = DropLabel()
            self.checkBox_Short.setEnabled(True)
            self.checkBox_Long.setEnabled(True)

    def setBoxSizes(self):
        if self.checkBox_Short.isChecked():
            boxSize = 40
        else:
            boxSize = 45

        for label in self.labels:
            label.setFixedSize(boxSize, boxSize)
            label.setLimits(self.UserImageLbl.geometry())
            label.show()
© www.soinside.com 2019 - 2024. All rights reserved.