A problem with drag and drop progressbar
-
I wish that my progressbar can be moved without creating a new one , the problem with this code is that it create a new progressbar when mouse click is released. Please help me.
@
void DropWidget::dropEvent(QDropEvent *event)
{if (event->mimeData()->hasFormat("application/x-dnditemdata")) { QPoint offset; QProgressBar *p=new QProgressBar(this); p->move(event->pos() - offset); p->setValue(70); p->setFixedWidth(200); p->show(); p->setAttribute(Qt::WA_DeleteOnClose); p->setAcceptDrops(true); p->setFocusPolicy(Qt::StrongFocus); if (event->source() == this) { event->setDropAction(Qt::MoveAction); event->accept(); } else { event->acceptProposedAction(); } } else { event->ignore(); }
}
//! [1]
void DropWidget::mousePressEvent(QMouseEvent *event)
{
QProgressBar child = static_cast<QProgressBar>(childAt(event->pos()));
if (!child)
return;
QByteArray itemData;
QDataStream dataStream(&itemData, QIODevice::WriteOnly);
dataStream << child << QPoint(event->pos() - child->pos());//! [1]
//! [2]
QMimeData *mimeData = new QMimeData;
mimeData->setData("application/x-dnditemdata", itemData);
//! [2]//! [3]
QDrag *drag = new QDrag(this);
drag->setMimeData(mimeData);
drag->setHotSpot(event->pos() - child->pos());
//! [3]
if (!drag->exec(Qt::CopyAction | Qt::MoveAction, Qt::CopyAction) == Qt::MoveAction) {
child->close();
} else{
child->show();
}
}
@ -
Well... Couldn't you just use one global QProgressBar? Instead of creating a child in mousePressEvent you could just check to see if the event->pos() corresponds with the progressbars pos...
-
sorry but I don't have just one progressbar so I need another solution.
-
In your implementation you are starting your drag on mousePressEvent() , so everytime when mousePressEvent is returned your dropEvent() is called which in turn creates a new QProgressBar at line 6.
You need to implement you QDrag in a new function startDrag() and inside mouseMoveEvent() you can check for the minimum distance and then call startDrag() function.
For eg
@void DropWidget::mouseMoveEvent(QMouseEvent *event)
{.... ....
// dragPoint = event->pos(); comes from mousePressEvent()
int distance = (event->pos()- dragPoint).manhattanLength();if (distance >=QApplication::startDragDistance()) { startDrag(Qt::MoveAction); }
}@
@void DropWidget::startDrag(Qt::DropActions supportedActions)
{QProgressBar child = static_cast<QProgressBar>(childAt(event->pos()));
if (!child)
return;QByteArray itemData; QDataStream dataStream(&itemData, QIODevice::WriteOnly); dataStream << child << QPoint(event->pos() - child->pos());
//! [1]
//! [2]QMimeData *mimeData = new QMimeData; mimeData->setData("application/x-dnditemdata", itemData);
//! [2]
//! [3]
QDrag *drag = new QDrag(this);
drag->setMimeData(mimeData);
drag->setHotSpot(event->pos() - child->pos());
//! [3]if (!drag->exec(Qt::CopyAction | Qt::MoveAction, Qt::CopyAction) == Qt::MoveAction)
{
child->close();} else { child->show(); }
}@
-
I don't understand why distance is used in this code , my problem is that i can't move the progressbar , I always get a new copy
-
Well the above implementation is another way of doing it. The distance is a constraint that is used to start the drag only after the item is clicked and moved to a minimum distance, which in your case is not required.
In your implementation change line 49 from
@if (!drag->exec(Qt::CopyAction | Qt::MoveAction, Qt::CopyAction) == Qt::MoveAction) @
to
@if (drag->exec(Qt::CopyAction | Qt::MoveAction, Qt::CopyAction) == Qt::MoveAction) @