PDA

View Full Version : QDrag seems to block mouse events.



Weener
13th August 2013, 09:18
Hi,

Firstly - thanks - the amount of gold in this forum has allowed me to trawl for answers for about 6 months, and not have to post. I'm impressed!

Unfortunately I am pretty confident I actually have an issue here. Hopefully I am being stupid, for that would mean a simple fix is in order.

I've sub classes QTreeView, and enabled it to provide a QDrag object, on mouse move. The trouble is; once the drag is over, signals like 'entered' are no longer emitted; and this is my issue; I'd like them back.

Below is a minimal coding example that produces the issue;

The TreeView shows the current item highlighted under the cursor, then after the drag, this stops, and the "ItemEntered" slot is never called. (Items don't have to be dragged anywhere - the drag just has to start - and things break)

Any help would be most appreciated.

Thanks




#include <QApplication>
#include <QStandardItemModel>
#include <QTreeView>
#include <QMouseEvent>

//////////////////////////////////////////////////////
// This is so we can provide "drag from" to the main window.
class DragAndDropTreeView : public QTreeView
{
Q_OBJECT
public:
DragAndDropTreeView(QObject * parent) ;

public slots:
void ItemEntered(const QModelIndex & index) ;

protected:
void mousePressEvent(QMouseEvent *) ;
void mouseMoveEvent(QMouseEvent *) ;
void mouseReleaseEvent(QMouseEvent *) ;

QPoint _clickPoint ;
int _activeItem ;
bool _mouseDown ;
bool _displayingShadow ;
} ;

DragAndDropTreeView::DragAndDropTreeView(QObject * parent)
{
_mouseDown = false ;
_displayingShadow = false ;
setMouseTracking(true);
connect(this,SIGNAL(entered(const QModelIndex &)),this,SLOT(ItemEntered(const QModelIndex &))) ;
}

void DragAndDropTreeView::mousePressEvent(QMouseEvent * e)
{
_clickPoint = e->pos() ;
setCursor(Qt::ClosedHandCursor);
QTreeView::mousePressEvent(e) ;
// this is ugly, and probably inefficient.
_activeItem = selectedIndexes()[0].sibling(selectionModel()->currentIndex().row(),0).data().toInt() ; ;
_mouseDown = true ;
}

void DragAndDropTreeView::mouseMoveEvent(QMouseEvent * e)
{
if (!_mouseDown)
{
QTreeView::mouseMoveEvent(e) ;
return ;
}
if (QLineF(e->pos(), _clickPoint).length() < QApplication::startDragDistance())
{
QTreeView::mouseMoveEvent(e) ;
return;
}

QDrag *drag = new QDrag(this) ;
if (drag == NULL) return ;
QMimeData *mime = new QMimeData ;
if (mime == NULL) return ;
drag->setMimeData(mime) ;

mime->setText(QString("Temp/%1").arg(_activeItem));

// note to the unwary !! THIS BLOCKS!
drag->exec() ;
QTreeView::mouseMoveEvent(e) ;
}

void DragAndDropTreeView::mouseReleaseEvent(QMouseEvent * e)
{
_mouseDown = false ;
QTreeView::mouseReleaseEvent(e) ;
}

// this is called properly before any drag event - but not after.
void DragAndDropTreeView::ItemEntered(const QModelIndex & index)
{
_displayingShadow = true ;
}


int main(int argc, char * argv[])
{
QApplication app(argc,argv);

DragAndDropTreeView * DDTV = new DragAndDropTreeView(NULL) ;

// set up the model to accept data.
QStandardItemModel * _model = new QStandardItemModel(0, 1) ;
// slap some stuff in.
_model->setHeaderData(0, Qt::Horizontal, QObject::tr("Number"));
for (int i = 0 ; i < 10 ; i++)
{
_model->insertRow(i);
_model->setData(_model->index(i, 0), QString("%1").arg(i));
}
// show all the beauty of it
DDTV->setRootIsDecorated(false) ;
DDTV->setModel(_model) ;
DDTV->setDragEnabled(true) ;
DDTV->setSortingEnabled(true) ;
DDTV->setSelectionMode(QAbstractItemView::SingleSelectio n) ;
DDTV->show() ;
return app.exec();
}

Santosh Reddy
13th August 2013, 13:17
Add this


void DragAndDropTreeView::mouseMoveEvent(QMouseEvent * e)
{
//....
_mouseDown = false; //<<<<<<<<<< Add in the end
}

void DragAndDropTreeView::mouseReleaseEvent(QMouseEvent * e) //<<<<< Mouse release event will not be called when drag is released, as it will be captured by QDrag
{
_mouseDown = false ;
QTreeView::mouseReleaseEvent(e) ;
}

Weener
13th August 2013, 21:46
Oh - my. Thanks. Well - at least this fits into the simple fix category. Sorry to trouble you.