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

Posted

技术标签:

【中文标题】当 setAcceptDrops 设置设置为 True 时,如何检测 QListWidet 内部移动信号【英文标题】:How do you detect QListWidet internal move signal while setAcceptDrops setting is set to True 【发布时间】:2020-04-09 09:40:02 【问题描述】:

我正在尝试在执行拖放效果时检测来自 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_())

【问题讨论】:

【参考方案1】:

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

def dragEnterEvent(自我,事件): 如果 event.mimeData().hasUrls(): 事件.accept() 别的: super().dragEnterEvent(event) def dragMoveEvent(自我,事件): 如果 event.mimeData().hasUrls(): event.setDropAction(Qt.CopyAction) 事件.accept() 别的: super().dragMoveEvent(事件) def dropEvent(自我,事件): 如果 event.mimeData().hasUrls(): event.setDropAction(Qt.CopyAction) 事件.accept() pdf文件 = [] 对于 event.mimeData().urls() 中的 url: 如果 url.isLocalFile(): pdfFiles.append(str(url.toLocalFile())) self.addItems(pdfFiles) 别的: super().dropEvent(事件)

【讨论】:

感谢您的解决方案,它运行良好。肯定会深入研究 event.source() 方法以了解有关用法的更多信息。答案标记为解决方案。

以上是关于当 setAcceptDrops 设置设置为 True 时,如何检测 QListWidet 内部移动信号的主要内容,如果未能解决你的问题,请参考以下文章

Qt 子控件在设置setAcceptDrops后拖入显示禁止图标解决方法

如何将 id 设置为从 JSON 响应生成的 <tr>?

VUE 监听局部滚动 设置ICON的位置跟随

js中怎样设置动态tr的属性

关于html中table表格tr,td的高度和宽度

Handsontable 如何手动将单元格设置为无效