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