PyQt Drop Event Without Subclassing?
This python pyqt code works how I intended. But, I don't like having to subclass QLineEdit so that I can detect file drop onto my QLineEdit field. I like the more elegant and simp
Solution 1:
No need to subclass: you can use an event filter:
import sys
from PyQt4 import QtGui, QtCore
class testDialog(QtGui.QDialog):
def __init__(self, parent=None):
super(testDialog, self).__init__(parent)
form = QtGui.QFormLayout()
form.setHorizontalSpacing(0)
self.myedit = QtGui.QLineEdit()
self.myedit.setDragEnabled(True)
self.myedit.setAcceptDrops(True)
self.myedit.installEventFilter(self)
form.addWidget(self.myedit)
self.setLayout(form)
self.setGeometry(300, 300, 400, 0)
self.setWindowTitle('drop test')
self.myedit.textChanged.connect(self.editchange) # new style signal slot connections
@QtCore.pyqtSlot(str) # int represent the column value
def editchange(self,data):
print "editchange:", data.toLatin1()
def eventFilter(self, object, event):
if (object is self.myedit):
if (event.type() == QtCore.QEvent.DragEnter):
if event.mimeData().hasUrls():
event.accept() # must accept the dragEnterEvent or else the dropEvent can't occur !!!
print "accept"
else:
event.ignore()
print "ignore"
if (event.type() == QtCore.QEvent.Drop):
if event.mimeData().hasUrls(): # if file or link is dropped
urlcount = len(event.mimeData().urls()) # count number of drops
url = event.mimeData().urls()[0] # get first url
object.setText(url.toString()) # assign first url to editline
#event.accept() # doesnt appear to be needed
return False # lets the event continue to the edit
return False
if __name__ == "__main__":
app = QtGui.QApplication([])
dl = testDialog()
dl.exec_()
sys.exit(app.closeAllWindows())
Solution 2:
I had the same issue today and has able to get it solved in a different (and maybe less orthodoxy) way. So, what can also be done is to remap the dropEvent function from the tree to another name, either internal to the instance or to the class that owns the instance, and assign a new custom function the dropEvent. This new function can call or not the original one, depending if you want to keep some of the functionallities, or just rewrite everything. Here is a snippet:
import sys
from PyQt5.QtWidgets import QTreeView
from PyQt5.QtGui import QDropEvent
class Demo:
def __init__(self):
self.tree = QTreeView()
self.tree.setDragEnabled(True)
self.tree.setAcceptDrops(True)
self.tree.original_dropEvent = self.dataView.dropEvent
self.tree.dropEvent = self._dataview_dropevent
def _tree_dropevent(self, event: QDropEvent):
# do stuff ...
self.tree.original_dropEvent(event)
# maybe more stuff ..
.
Post a Comment for "PyQt Drop Event Without Subclassing?"