Unsolved QAction, QToolButton, QToolBar & drag n drop
-
Hey
I'm trying to learn how I can implement a drag and drop on QToolBar... so far its quite interesting journey.
In essence what I understand so far is that QToolBar, holds QWidgets which points to QActions(widget->defaultAction());
(below code kinds jumps between eventFilter and dragEnterEvent/dropEvent)
So I have installed event filter(Qtoolbar one) on all my QWidgets inside QToolBar via a loop findChild<QWidget*>();
If I perform drag&drop operation on a QAction/QToolButton I'm doing something like : >
bool icToolBar::eventFilter(QObject *watched, QEvent *event) { if (event->type() == QEvent::Enter) { qDebug() << watched; if (!mPressed)mLastAction = static_cast<QToolButton *>(watched)->defaultAction(); // make sure I did not already press on some button/action. } if (event->type() == QEvent::Leave) { if (mLastAction && mPressed) { qDebug() << "I had last action thini so i must be dragging?"; } if (!mPressed) { mLastAction = nullptr; // clear the last action entered }; } if (event->type() == QEvent::MouseButtonPress) { mInitialPos = static_cast<QMouseEvent *>(event)->pos(); // I need it to determine drag trigger mButton = static_cast<QMouseEvent *>(event)->button(); // need to know which button for later reference mPressed = true; } if (event->type() == QEvent::MouseMove) { if (mPressed && mLastAction != nullptr) { // ensuring that I pressed on a button and that i have it stored. if ((static_cast<QMouseEvent *>(event)->pos() - mInitialPos).manhattanLength() >= QApplication::startDragDistance()) { performDragOp(); } } } if (event->type() == QEvent::MouseButtonRelease) { mPressed = false; mLastAction = nullptr; mButton = Qt::NoButton; } return QObject::eventFilter(watched, event); } void icToolBar::performDragOp() { icInternalMime *mimeData = new icInternalMime(); // my custom mime mimeData->setMimeType(mType); // setting mime type mimeData->setActionBtn(mLastAction); // setting button I captured early QDrag *drag = new QDrag(this); // standard drag drag->setMimeData(mimeData); switch (mButton) { case (Qt::LeftButton): { // deciding which drag type I want to have - no idea if thats the right way tho. drag->exec(Qt::MoveAction); break; } case (Qt::RightButton): { drag->exec(Qt::CopyAction); break; } } //// no idea if that stuff needs to be here, debug decide. mPressed = false; mLastAction = nullptr; mButton = Qt::NoButton; //I presume after drag.exec() finishes this code runs next... How can I then clear the action that I pressed on. It remaing in a "press state" } void icToolBar::dropEvent(QDropEvent *event) { event->accept(); qDebug() << "im being dropped?"; // yay ? const icInternalMime *mim = dynamic_cast<const icInternalMime *>(event->mimeData()); QAction *act = mim->getActionBtn(); // retrieve action act->installEventFilter(this); // this dont work - and this is the issue. The newly added action, does not have event filter properly installed. So I cant drag it again... addAction(act); // so this properly adds the action back to the toolbar - BUT, will the early configured signal connect() still work? /// In future use insertAction() in order to specify exact position according to hover/drop/position cursor. QWidget::dropEvent(event); }
Now here i have 3 issues.
- Once Action gets dropped and re-added. Its event filter is incorrect. I need to re-install event filter on it again. How can I do this ? I can always loop over all children again but that feels "wrong".
- If drop action is refused. The original button I pressed on to drag remain pressed. How can I reset its state?
3 . More question than issue. But if I execute the drag/drop this way. Do I need to re-configure connection() on action trigger? I'm hoping that it will still point to the right "command" ?
TIA :- )
-
Bump bump bump help :- )