Warning: file_get_contents(/data/phpspider/zhask/data//catemap/8/qt/7.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Qt 如何检测QStandardItemModel中的一个项目被放到另一个项目上?_Qt_Python 3.x_Drag And Drop_Pyqt_Pyqt5 - Fatal编程技术网

Qt 如何检测QStandardItemModel中的一个项目被放到另一个项目上?

Qt 如何检测QStandardItemModel中的一个项目被放到另一个项目上?,qt,python-3.x,drag-and-drop,pyqt,pyqt5,Qt,Python 3.x,Drag And Drop,Pyqt,Pyqt5,我如何接收到一个通知,即a被拖放到另一个QStandardItem上,从而成为后者的子项 我原以为可以通过重新实现来实现这一点,但在删除后不会调用它:(下面是我尝试执行的一个示例。要进行测试,请运行程序并将树视图中的一项删除到另一项上。如果成功,您应该在控制台中看到已调用moveRows的确认 from PyQt5.QtGui import * from PyQt5.QtWidgets import * from PyQt5.QtCore import * class Model(QStan

我如何接收到一个通知,即a被拖放到另一个QStandardItem上,从而成为后者的子项

我原以为可以通过重新实现来实现这一点,但在删除后不会调用它:(下面是我尝试执行的一个示例。要进行测试,请运行程序并将树视图中的一项删除到另一项上。如果成功,您应该在控制台中看到已调用
moveRows
的确认

from PyQt5.QtGui import *
from PyQt5.QtWidgets import *
from PyQt5.QtCore import *


class Model(QStandardItemModel):
    def moveRows(
            self, source_parent, source_row, count, destination_parent,
            destination_child):
        print(
            'Moving {} row(s) from row {} of parent {} to row {} of parent {}'
            .format(
                count, source_row, source_parent, destination_child,
                destination_parent)
        )
        super().moveRows(
            source_parent, source_row, count, destination_parent,
            destination_child)
        return True


def _create_item(text):
    item = QStandardItem(text)
    flags = Qt.ItemIsDragEnabled | Qt.ItemIsSelectable | Qt.ItemIsEnabled | Qt.ItemIsDropEnabled
    item.setFlags(flags)
    return item


model = Model()
model.appendRow([_create_item('Item 1')])
model.appendRow([_create_item('Item 2')])

app = QApplication([])
view = QTreeView()
view.setDragDropMode(view.InternalMove)
view.setModel(model)
view.show()
app.exec_()

通过研究QStandardItemModel源代码,我意识到必须重写,以便对条目丢失做出反应。QStandardItemModel在其
dropMimeData
的实现中移动条目,但子类无法以某种方式连接,因此您必须自己处理
dropMimeData

这是基于my
dropMimeData
的解决方案,MIME数据中包含的项目表示形式为Python pickle:

import pickle
from PyQt5.QtGui import *
from PyQt5.QtWidgets import *
from PyQt5.QtCore import *


_mimeType = 'application/x-standarditemmodeldatalist'


class Model(QStandardItemModel):
    def dropMimeData(
            self, data, action, row, column, parent):
        # Access parent before calling super implementation, because it may mutate parent
        dest_str = 'parent {}'.format(parent.data(Qt.DisplayRole)) if \
            parent.isValid() else 'root'

        ret_val = super().dropMimeData(data, action, row, column, parent)
        if action != Qt.MoveAction or not data.hasFormat(_mimeType):
            return ret_val

        item_data = pickle.loads(data.data(_mimeType))[0]
        print('Moving {} to {}'.format(item_data, dest_str))
        return True

    # Override in order to add custom MIME data
    def mimeData(self, indexes):
        mimeData = super().mimeData(indexes)
        data = [index.data(Qt.DisplayRole) for index in indexes]
        mimeData.setData(_mimeType, pickle.dumps(data))

        return mimeData

    # Override in order to announce our custom MIME type
    def mimeTypes(self):
        return super().mimeTypes() + [_mimeType]


def _create_item(text):
    item = QStandardItem(text)
    flags = Qt.ItemIsDragEnabled | Qt.ItemIsSelectable | Qt.ItemIsEnabled | Qt.ItemIsDropEnabled
    item.setFlags(flags)
    return item


model = Model()
model.appendRow([_create_item('Item 1')])
model.appendRow([_create_item('Item 2')])

app = QApplication([])
view = QTreeView()
view.setDragDropMode(view.InternalMove)
view.setModel(model)
view.show()
app.exec_()