pyqt5 覆盖 dropEvent python

pyqt5 override dropEvent python

我正在尝试向小型应用程序添加拖放功能。从 QlistWidget 获取数据并将数据拖放到 QTableWidget 上。我应该覆盖 QTableWidget 的 dropEvent 以便在删除数据时添加一些其他功能。但是我遇到了麻烦,我想我无法获取从 ListWidget 获取的对象的 text()。这是代码:

class Table(QtWidgets.QTableWidget):
    def __init__(self,r,c, parent=None):
        super().__init__(r,c,parent)    
        self.init_ui()

    def init_ui(self):            
        self.setAcceptDrops(True)
        self.setDragDropMode(QtWidgets.QAbstractItemView.DragDrop)

    """def dragMoveEvent(self, e):            
        e.setDropAction(QtCore.Qt.MoveAction)
        e.accept()

    def dragEnterEvent(self,e):            
        e.accept()"""      



    def dropEvent(self,e):            
        data = e.mimeData()
        a=e.pos()
        row = self.rowAt(a.y())
        col = self.columnAt(a.x())
        self.setItem(row,col,QtWidgets.QTableWidgetItem(data.text()))

        print(row,col)
        print(type(data.text()))
        print(e.source())
        x = data.text()
        print(x)
        e.accept()
`

QListWidget通过拖放传输的数据不是通过text()给出的,因为一个项目有更多的角色标识的信息,此外你可以拖动几个项目。数据使用MIME类型application/x-qabstractitemmodeldatalist传输,解决方法如下图解码:

from PyQt5 import QtCore, QtWidgets


class TableWidget(QtWidgets.QTableWidget):
    def __init__(self, r,c, parent=None):
        super(TableWidget, self).__init__(r,c, parent)
        self.setAcceptDrops(True)
        self.setDragDropMode(QtWidgets.QAbstractItemView.DropOnly)


    def dropEvent(self, event):
        md = event.mimeData()
        fmt = "application/x-qabstractitemmodeldatalist"
        if md.hasFormat(fmt):
            encoded = md.data(fmt)
            stream = QtCore.QDataStream(encoded, QtCore.QIODevice.ReadOnly)
            table_items = []
            while not stream.atEnd():
                # row and column where it comes from
                row = stream.readInt32()
                column = stream.readInt32()
                map_items = stream.readInt32()
                it = QtWidgets.QTableWidgetItem()

                for i in range(map_items):
                    role = stream.readInt32()
                    value = QtCore.QVariant()
                    stream >> value
                    it.setData(role, value)
                table_items.append(it)

            for it in table_items:
                print(it, it.text())


class MainWindow(QtWidgets.QMainWindow):
    def __init__(self, parent=None):
        super(MainWindow, self).__init__(parent)
        list_widget = QtWidgets.QListWidget()
        list_widget.setAcceptDrops(False)
        list_widget.setEditTriggers(QtWidgets.QAbstractItemView.NoEditTriggers)
        list_widget.setDragDropMode(QtWidgets.QAbstractItemView.DragOnly)
        for i in range(10):
            it = QtWidgets.QListWidgetItem("item-{}".format(i))
            list_widget.addItem(it)

        table_widget = TableWidget(5, 10)
        central_widget = QtWidgets.QWidget()
        hlay = QtWidgets.QHBoxLayout(central_widget)
        hlay.addWidget(list_widget)
        hlay.addWidget(table_widget)
        self.setCentralWidget(central_widget)


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