当 setAcceptDrops 设置设置为 True 时如何检测 QListWidet 内部移动信号

How do you detect QListWidet internal move signal while setAcceptDrops setting is set to True

我在使用拖放效果器时试图检测来自 QListWidget 的内部移动信号。但目前使用我的代码,因为我正在自行处理 dragEnterEvent、dragMoveEvent 和 moveEvent,所以忽略了内部移动信号。有什么办法可以解决这个问题吗?下面是复制问题的简单代码。

您可以将外部项目拖动到列表小部件,但现在无法移动项目。

import sys, os
from PyQt5.QtWidgets import QApplication, QWidget, QLabel, QLineEdit, QListWidget, \
                            QVBoxLayout, QHBoxLayout, QAbstractItemView
from PyQt5.QtCore import Qt

class ListWidget(QListWidget):
    def __init__(self, parent=None):
        super().__init__(parent=None)
        self.setAcceptDrops(True)
        self.setStyleSheet('''font-size:25px''')

    def dragEnterEvent(self, event):
        # print(event.mimeData().urls())
        # print(dir(event.mimeData()))
        if event.mimeData().hasUrls():
            event.accept()
        else:

            event.ignore()

    def dragMoveEvent(self, event):

        if event.mimeData().hasUrls():
            event.setDropAction(Qt.CopyAction)
            event.accept()
        else:
            print('y')
            event.ignore()

    def dropEvent(self, event):
        if event.mimeData().hasUrls():
            event.setDropAction(Qt.CopyAction)
            event.accept()

            pdfFiles = []

            for url in event.mimeData().urls():
                if url.isLocalFile():                   
                    pdfFiles.append(str(url.toLocalFile()))
            self.addItems(pdfFiles)
        else:
            event.ignore()

class AppDemo(QWidget):
    def __init__(self):
        super().__init__()
        self.resize(1200, 800)

        data = ['Microsoft', 'Facebook', 'Google']
        mainLayout = QHBoxLayout()


        self.lst = ListWidget()
        self.lst.addItems(data)
        self.lst.setStyleSheet('''
            font-size:30px
        ''')
        self.lst.setDragDropMode(QAbstractItemView.InternalMove)



        mainLayout.addWidget(self.lst)

        self.setLayout(mainLayout)

if __name__ == '__main__':
    app = QApplication(sys.argv)

    demo = AppDemo()
    demo.show()

    sys.exit(app.exec_())

不是在 mimedata 没有 url 时调用 event.ignore(),而是调用父级的方法,以便像默认 QListWidget 一样处理拖放。此外,另一种确定拖动操作来源的方法是 event.source()

def dragEnterEvent(self, event):
    if event.mimeData().hasUrls():
        event.accept()
    else:
        super().dragEnterEvent(event)

def dragMoveEvent(self, event):
    if event.mimeData().hasUrls():
        event.setDropAction(Qt.CopyAction)
        event.accept()
    else:
        super().dragMoveEvent(event)

def dropEvent(self, event):
    if event.mimeData().hasUrls():
        event.setDropAction(Qt.CopyAction)
        event.accept()
        pdfFiles = []
        for url in event.mimeData().urls():
            if url.isLocalFile():                   
                pdfFiles.append(str(url.toLocalFile()))
        self.addItems(pdfFiles)
    else:
        super().dropEvent(event)