我正在 QTableView 中进行自定义拖放实现。当我拖动一个单元格并将其放在另一个单元格上时,我想根据拖动的内容和放置的位置手动更改模型中的一些数据。我怎样才能做到这一点?我已经阅读了所有 Qt 文档,但我完全迷失了,特别是通过拖放,C++ 到 PyQt 的转换似乎不太直观。
基本上我需要的是,当我放下时,我想知道哪些单元格最初被拖动,以及它们被放在哪里。我的困惑似乎在于 QMimeData。据我所知,拖动开始时,拖动事件接收到正确的 MIME 数据,但我不知道如何在 PyQt 中获取它(过去能够使用文本和 url 执行此类操作,但我'当涉及到项目视图时我迷失了)。我还需要知道我要去哪里。我想我可以做一个“光标位置的项目”,但我假设这个数据已经存在于放置事件中,我只需要弄清楚如何查询它。
这是一个简单的例子:
import sys
from PyQt4 import QtGui, QtCore
class TableView(QtGui.QTableView):
def __init__(self, parent=None):
QtGui.QTreeWidget.__init__(self, parent)
self.setDragEnabled(True)
self.setDropIndicatorShow(True)
self.setDragDropMode(QtGui.QAbstractItemView.DragDrop)
self.setDragDropOverwriteMode(False)
self.setSelectionBehavior(QtGui.QAbstractItemView.SelectRows)
def dragEnterEvent(self, event):
event.accept()
def dropEvent(self, event):
# I want to do cool things with the dragged cells, and I need to know where they dropped!
print(event.mimeData().formats()) # this tells me that I shuld get some sort of "qabstractitemmodeldatalist". Sounds promising...
print(event.mimeData().data("application/x-qabstractitemmodeldatalist")) # this gives me an interesting looking QByteArray but I have no idea what to do with it...
event.accept()
class Dialog(QtGui.QDialog):
def __init__(self):
super(Dialog, self).__init__()
model = QtGui.QStandardItemModel(self)
model.insertRow(0, QtGui.QStandardItem("C"))
model.insertRow(0, QtGui.QStandardItem("B"))
model.insertRow(0, QtGui.QStandardItem("A"))
table = TableView(self)
table.setModel(model)
app = QtGui.QApplication(sys.argv)
ex = Dialog()
ex.show()
sys.exit(app.exec_())
您无法知道它被拖动到哪里,因为 mimeData 没有该信息,但您可以获取拖动的数据,为此我们创建了一个临时模型,我们将在其中建立模拟相同拖动行为的 mimeData。要获取它被删除的位置,作为事件一部分的位置必须与 indexAt() 一起使用,从而获取 QModelIndex:
import sys
from PyQt4 import QtGui, QtCore
class TableView(QtGui.QTableView):
def __init__(self, parent=None):
QtGui.QTreeWidget.__init__(self, parent)
self.setDragEnabled(True)
self.setDropIndicatorShown(True)
self.setDragDropMode(QtGui.QAbstractItemView.DragDrop)
self.setDragDropOverwriteMode(False)
self.setSelectionBehavior(QtGui.QAbstractItemView.SelectRows)
def dragEnterEvent(self, event):
event.accept()
def dropEvent(self, event):
if self.viewport().rect().contains(event.pos()):
fake_model = QtGui.QStandardItemModel()
fake_model.dropMimeData(
event.mimeData(), event.dropAction(), 0, 0, QtCore.QModelIndex()
)
print("from:")
for r in range(fake_model.rowCount()):
for c in range(fake_model.columnCount()):
ix = fake_model.index(r, c)
print(ix.data())
to_index = self.indexAt(event.pos())
if to_index.isValid():
print("to:", to_index.data())
super(TableView, self).dropEvent(event)
class Dialog(QtGui.QDialog):
def __init__(self):
super(Dialog, self).__init__()
model = QtGui.QStandardItemModel(self)
for letter in "ABC":
model.appendRow(QtGui.QStandardItem(letter))
table = TableView()
table.setModel(model)
lay = QtGui.QVBoxLayout(self)
lay.addWidget(table)
if __name__ == "__main__":
app = QtGui.QApplication(sys.argv)
ex = Dialog()
ex.show()
sys.exit(app.exec_())
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)