Перетащите QLabels с PyQt5 - PullRequest
0 голосов
/ 08 мая 2018

Я пытаюсь перетащить Qlabel на другой Qlabel с PyQt5:

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), и перетащив его на второй ярлык, чтобы изменить его текст. Перетаскивание текста из другого приложения работает нормально, но я не могу найти, как перетащить 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() всегда возвращает ложь ... Неправильно ли я настроил изображение?

1 Ответ

0 голосов
/ 09 мая 2018

В случае QLabel вы должны создать все с самого начала, для этого вы можете следовать примерам документов .

В следующем примере я поместил пример, в котором один класс принимает только перетаскивание, а другой - перетаскивание, чтобы вы могли видеть каждую часть и лучше понимать.

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

Обновление:

Не путайте QDrag с QMimeData, если вы хотите использовать imageData(), вы должны установить его на setImageData(), как указано в документах :

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