使用PyQt5拖放QLabel

Posted

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了使用PyQt5拖放QLabel相关的知识,希望对你有一定的参考价值。

我正在尝试使用PyQt5将Qlabel拖放到另一个Qlabel上:

from PyQt5.QtWidgets import QApplication, QWidget, QToolTip, QPushButton, QMessageBox, QHBoxLayout, QVBoxLayout, QGridLayout,QFrame, QComboBox, QLabel, QLineEdit
from PyQt5.QtGui import QIcon, QFont, QPixmap, QImage
import sys


class my_label(QLabel):
    def __init__(self,title,parent):
        super().__init__(title,parent)
        self.setAcceptDrops(True)

    def dragEnterEvent(self,event):
        if event.mimeData().hasFormat("text/plain"):
            event.accept()
        else:
            event.ignore()
    def dropEvent(self,event):
        self.setText(event.mimeData().text())


class application(QWidget):

    def __init__(self):
        super().__init__()
        self.initUI()

    def initUI(self):


        label = my_label("drop there",self)
        label.resize(100,100)
        label.move(190,65)

        label_to_drag = QLabel("drag this",self)
        #label_to_drag.setDragEnabled(True)    #doesn't work with QLabel        
        self.show()


    def closeEvent(self,event):
        message = QMessageBox.question(self,"Message","Quit ?",QMessageBox.Yes | QMessageBox.No,QMessageBox.No)

        if message == QMessageBox.Yes:
            event.accept()
        else:
            event.ignore()

app = QApplication(sys.argv)
fenetre = application()
sys.exit(app.exec_())

我想通过调用setDragEnabled(True)方法(就像我为QLineEdit做的那样)使我的第一个标签“draggable”,并将其放在第二个标签上以更改其文本。从另一个应用程序中删除文本工作正常,但我找不到如何在我自己的应用程序中拖动QLabel ...我错过了什么?

编辑:修改代码以尝试拖放图像:

class DraggableLabel(QLabel):
def __init__(self,parent,image):
    super(QLabel,self).__init__(parent)
    self.setPixmap(QPixmap(image))    
    self.show()
def mousePressEvent(self, event):
    if event.button() == Qt.LeftButton:
        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())

    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 my_label(QLabel):
    def __init__(self,title,parent):
        super().__init__(title,parent)
        self.setAcceptDrops(True)

    def dragEnterEvent(self,event):
        if event.mimeData().hasFormat("text/plain"):
            print("event accepted")
            event.accept()
        else:
            print("event rejected")
            event.ignore()
    def dropEvent(self,event):
        if event.mimeData().hasImage():
            self.setPixmap(QPixmap.fromImage(QImage(event.mimeData().imageData())))

class application(QWidget):

    def __init__(self):
        super().__init__()
        self.initUI()

    def initUI(self):

        label_to_drag = DraggableLabel(self,"index.jpg")

        label = my_label("drop there",self)
        label.resize(100,100)
        label.move(190,65)



        self.show()

当我在DraggableLabel上放下my_label(显示图像)时,事件被接受,但hasImage()总是返回false ...我设置图像的方式是错误的吗?

答案

QLabel的情况下,您必须从头开始创建所有内容,为此您可以按照docs的示例进行操作。

在下面的示例中,我放置了一个示例,其中一个类仅接受drop,另一个类接受拖动,以便您可以看到每个部分并更好地理解。

import sys

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


class DraggableLabel(QLabel):
    def mousePressEvent(self, event):
        if event.button() == Qt.LeftButton:
            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())
        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()
        text = event.mimeData().text()
        self.setText(text)
        event.acceptProposedAction()


class Widget(QWidget):
    def __init__(self):
        super().__init__()
        self.initUI()

    def initUI(self):
        label = DropLabel("drop there",self)
        label.setGeometry(190, 65, 100,100)

        label_to_drag = DraggableLabel("drag this",self)  
        self.show()

if __name__ == '__main__':
    app = QApplication(sys.argv)
    w = Widget()
    w.show()
    sys.exit(app.exec_())

更新:

不要混淆QDragQMimeData,如果你想使用imageData(),你必须用setImageData()设置docs

class DraggableLabel(QLabel):
    def __init__(self,parent,image):
        super(QLabel,self).__init__(parent)
        self.setPixmap(QPixmap(image))    
        self.show()
    def mousePressEvent(self, event):
        if event.button() == Qt.LeftButton:
            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 my_label(QLabel):
    def __init__(self,title,parent):
        super().__init__(title,parent)
        self.setAcceptDrops(True)

    def dragEnterEvent(self,event):
        if event.mimeData().hasImage():
            print("event accepted")
            event.accept()
        else:
            print("event rejected")
            event.ignore()
    def dropEvent(self,event):
        if event.mimeData().hasImage():
            self.setPixmap(QPixmap.fromImage(QImage(event.mimeData().imageData())))

以上是关于使用PyQt5拖放QLabel的主要内容,如果未能解决你的问题,请参考以下文章

PyQt5 QLabel 错误

使用 PyQt5 在 QLabel 中绘制图像

使用 QPainter 和 paintEvent 在 PYQT5 中的 QLabel 中包含的 Pixmap 上绘制圆圈

PyQt5 - QLabel 填充无法按预期工作

pyqt5 Qlabel控件添加图片单击进入网站

如何在 PyQt5 中将字节数组图像添加到 QLabel