5

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() 

1 Answer 1

8

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.

Sign up to request clarification or add additional context in comments.

1 Comment

Awesome, thank you, that does it! Also thanks for pointing out the layout issue. This was really only a test case for a more complicated case that I'm working on, so will see if that it impacts it at all.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.