Reputation: 3106
I'm struggling with getting drag&drop to work. I want to be able to drag&drop from a QPushButton into a cell of a QTableView. I've looked at a few tutorials online but seem to be stuck at the first step. The example below is changed from the amazing zetcode tutorial: http://zetcode.com/tutorials/pyqt4/dragdrop/
Using the code below, when I drag the button into tableWidget, the dragEnterEvent seems to be get called, but once I hover the mouse over the table, I get that symbol that I'm not allowed to drop over the table, so can never get to the drop event :(
I have to admit I'm fairly new to pyqt, so may be missing something very simple. Would really appreciate any help I could get! Cheers Dave
import sys
from PyQt4 import QtGui
from PyQt4 import QtCore
class Button(QtGui.QPushButton):
def __init__(self, title, parent):
super(Button, self).__init__(title, parent)
def mouseMoveEvent(self, e):
if e.buttons() != QtCore.Qt.RightButton:
return
mimeData = QtCore.QMimeData()
drag = QtGui.QDrag(self)
drag.setMimeData(mimeData)
drag.setHotSpot(e.pos() - self.rect().topLeft())
dropAction = drag.start(QtCore.Qt.MoveAction)
def mousePressEvent(self, e):
QtGui.QPushButton.mousePressEvent(self, e)
if e.button() == QtCore.Qt.LeftButton:
print 'press'
class MyTable(QtGui.QTableWidget):
def __init__(self, rows, columns, parent):
super(MyTable, self).__init__(rows, columns, parent)
self.setAcceptDrops(True)
def dragEnterEvent(self, e):
print e.accept()
def dropEvent(self, e):
print 'blah'
position = e.pos()
self.button.move(position)
e.setDropAction(QtCore.Qt.MoveAction)
e.accept()
class Example(QtGui.QWidget):
def __init__(self):
super(Example, self).__init__()
self.initUI()
def initUI(self):
self.setAcceptDrops(True)
self.button = Button('Button', self)
self.table = MyTable(2,2,self)
self.table.setAcceptDrops(True)
self.table.setDragEnabled(True)
self.setWindowTitle('Click or Move')
self.setGeometry(300, 300, 280, 150)
layout = QtGui.QVBoxLayout()
layout.addWidget(self.button)
layout.addWidget(self.table)
self.setLayout(layout)
def main():
app = QtGui.QApplication(sys.argv)
ex = Example()
ex.show()
app.exec_()
if __name__ == '__main__':
main()
Upvotes: 5
Views: 7915
Reputation: 92657
Because you are setting up drag and drop on a QTableWidget, you also need to re-implement it's dragMoveEvent
. As per the docs here:
Subclassing Complex Widgets
Certain standard Qt widgets provide their own support for drag and drop. When subclassing these widgets, it may be necessary to reimplement dragMoveEvent() in addition to dragEnterEvent() and dropEvent() to prevent the base class from providing default drag and drop handling, and to handle any special cases you are interested in.
class MyTable(QtGui.QTableWidget):
...
def dragMoveEvent(self, e):
e.accept()
Also, be aware that while the original tutorial shows how to move a button within a widget without any layouts, your example now has the button managed by a vertical layout. So your self.button.move(position)
will not work as expected. Though the dropEvent
should fire properly and you should be getting the "accepted" drag icon when it hovers a cell.
Upvotes: 7