I try to create a QTableView that can handle drop events. For reasons of application architecture, I want that to be done by an eventFilter of mine (that handles some QAction-triggers for clipboard interaction as well). But the drop-event does not seem to get through to the eventFilter.
I do not care where the data are dropped within the view. That is one of the reasons I want it to be handled by that eventFilter and not by the model. Furthermore, I do not want the model to pop up a dialog ("Are you sure to drop so many elements?"), because user interaction should be done by gui elements.
btw: It did actually work in Qt4/PySide.
I set up an example code snippet to illustrate the problem. The interesting thing about this is that there can appear QDrop Events, but only in the headers of the item view.
#!/usr/bin/env python2.7
# coding: utf-8
from PyQt5.QtWidgets import (
QApplication,
QMainWindow,
QTableView,
QWidget,
)
from PyQt5.QtCore import (
Qt,
QStringListModel,
QEvent
)
app = QApplication([])
window = QMainWindow()
# Table View with Drop-Options
view = QTableView(window)
view.setDropIndicatorShown(True)
view.setDragEnabled(True)
view.setAcceptDrops(True)
view.setDragDropMode(QTableView.DragDrop)
view.setDefaultDropAction(Qt.LinkAction)
view.setDropIndicatorShown(True)
window.setCentralWidget(view)
# Simple Event Filter for TableView
class Filter(QWidget):
def eventFilter(self, widget, event):
print widget, event, event.type()
if event.type() in (QEvent.DragEnter, QEvent.DragMove, QEvent.Drop):
print "Drag'n'Drop-Event"
if event.type() != QEvent.Drop:
print "\tbut no DropEvent"
event.acceptProposedAction()
else:
print "\tan actual DropEvent"
return True
return False
filter = Filter(window)
view.installEventFilter(filter)
class MyModel(QStringListModel):
# Model with activated DragDrop functionality
# vor view
def supportedDragActions(self):
print "asks supported drop actions"
return Qt.LinkAction | Qt.CopyAction
def canDropMimeData(self, *args):
print "canDropMimeData"
return True
def dropMimeData(self, *args):
print "dropMimeData"
return True
model = MyModel("Entry_A Entry_B Entry_C".split())
view.setModel(model)
window.show()
window.raise_()
app.exec_()
Final question: What widget handles the QDropEvents within the QTableView, or what widget should I install the eventFilter on?
view.viewport()
gets all the remaining events. So simply adding
view.viewport().installEventFilter(filter)
will do.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With