【问题标题】:Python PyQt5: QListWidget doesn't accept dropsPython PyQt5:QListWidget 不接受丢弃
【发布时间】:2017-08-07 21:12:25
【问题描述】:

我尝试创建一个简单的 QListWidget 来接受放入其中的文本。不能让它工作。 drop-event 甚至没有被触发,而 drag 事件是另一方面。 谁能指出我正确的方向?我做错了什么?

提前致谢。

import sys
from PyQt5.QtWidgets import QApplication, QWidget, QPushButton,  QLineEdit, QLabel, QListWidget
from PyQt5.QtGui import QIcon
from PyQt5.QtCore import pyqtSlot

class App(QWidget):

    def __init__(self):
        super().__init__()
        self.title = 'PyQt5 drag and drop'
        self.left = 500
        self.top = 400
        self.width = 400
        self.height = 250
        self.initUI()

    def initUI(self):
        self.setWindowTitle(self.title)
        self.setGeometry(self.left, self.top, self.width, self.height)

        editBox = QLineEdit('Drag this', self)
        editBox.setDragEnabled(True)
        editBox.move(10, 10)
        editBox.resize(100,32)

        listwidget = CustomLabel(self)
        listwidget.move(130,15)

        self.show()


class CustomLabel(QListWidget):

    def __init__(self, parent):
        super().__init__(parent)
        self.setAcceptDrops(True)

    def dragEnterEvent(self, e):
        if e.mimeData().hasFormat('text/plain'):
            print("dragged")
            e.accept()
        else:
            e.ignore()


    def dropEvent(self, e):
        print("dropped")

        self.addItem(event.mimeData().text())

if __name__ == '__main__':
    app = QApplication(sys.argv)
    ex = App()
    sys.exit(app.exec_())

【问题讨论】:

  • 您需要以某种方式启动拖动。看看drag and drop docs
  • 不明白...对不起
  • 这只告诉那个特定的小部件 accept 掉落——它与实际开始拖动操作无关。请阅读我第一条评论中链接到的文档。
  • 阅读文档对我没有启发,我必须说。无法完全理解那里的代码,因为我目前只熟悉python。

标签: python drag-and-drop qt5 pyqt5 qlistwidget


【解决方案1】:

默认情况下,QListWidget 不处理丢弃的文本,因此您必须重新实现 mime-data 处理,如下所示:

class CustomLabel(QListWidget):    
    def __init__(self, parent):
        super().__init__(parent)
        self.setAcceptDrops(True)

    def mimeTypes(self):
        mimetypes = super().mimeTypes()
        mimetypes.append('text/plain')
        return mimetypes

    def dropMimeData(self, index, data, action):
        if data.hasText():
            self.addItem(data.text())
            return True
        else:
            return super().dropMimeData(index, data, action)

【讨论】:

    【解决方案2】:

    看起来你的代码是基于this example

    主要区别在于您的CustomLabel 继承自QListWidget 而不是QLabel。不幸的是,QListWidget 继承自 QAbstractScrollArea,并且与该滚动区域相关联的视口小部件将接收各种拖放事件,而不是 QListWidget 本身。

    最好的办法可能是在视口上安装一个事件过滤器......

    class CustomLabel(QListWidget):
        def __init__(self, parent):
            super().__init__(parent)
            self.setAcceptDrops(True)
    
            # Install the event filter.
            self.viewport().installEventFilter(self)
    
        def dragEnterEvent(self, e):
            if e.mimeData().hasFormat('text/plain'):
                print("dragged")
                e.accept()
            else:
                e.ignore()
    
        def eventFilter (self, obj, event):
            if obj == self.viewport():
                print("event")
                if event.type() == QEvent.DragMove:
                    print("moved")
                    event.accept()
    
                    # Your drag enter event processing code goes here
                    return True
                if event.type() == QEvent.Drop:
                    print("dropped")
                    event.accept()
    
                    # Your drop event processing code goes here
                    return True
            return super(CustomLabel, self).eventFilter(obj, event)
    

    编辑 1:

    您可能还需要添加...

    from PyQt5.QtCore import QEvent
    

    【讨论】:

    • 你是对的,它是该示例的略微修改版本。我忘记了将类从 CustomLabel 重命名为其他名称。但是当我用您的代码替换 CustomLabel 类时,应用程序无法启动/没有显示窗口。
    • 编辑1
    【解决方案3】:

    太棒了。现在可以了。 非常感谢你的帮助。 这就是整个代码放在一起:

    import sys
    from PyQt5.QtWidgets import QApplication, QWidget,  QLineEdit, QListWidget
    
    
    class App(QWidget):
    
        def __init__(self):
            super().__init__()
            self.title = 'PyQt5 drag and drop'
            self.left = 500
            self.top = 400
            self.width = 400
            self.height = 250
            self.initUI()
    
        def initUI(self):
            self.setWindowTitle(self.title)
            self.setGeometry(self.left, self.top, self.width, self.height)
    
            editBox = QLineEdit('Drag this', self)
            editBox.setDragEnabled(True)
            editBox.move(10, 10)
            editBox.resize(100,32)
    
            listwidget = CustomList(self)
            listwidget.move(130,15)
    
            self.show()
    
    
    class CustomList(QListWidget):
    
        def __init__(self, parent):
            super().__init__(parent)
            self.setAcceptDrops(True)
    
        def mimeTypes(self):
            mimetypes = super().mimeTypes()
            mimetypes.append('text/plain')
            return mimetypes
    
        def dropMimeData(self, index, data, action):
            if data.hasText():
                self.addItem(data.text())
                return True
            else:
                return super().dropMimeData(index, data, action)
    
    
    if __name__ == '__main__':
        app = QApplication(sys.argv)
        ex = App()
        sys.exit(app.exec_())
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2010-11-29
      • 1970-01-01
      • 1970-01-01
      • 2023-03-05
      • 1970-01-01
      • 2012-09-21
      • 1970-01-01
      • 2018-02-14
      相关资源
      最近更新 更多