Change mouse icon on Macwhen performing a Drag Drop



  • Hi
    I try to reproduce the behavior of the OSX finder: by default it moves files/directories but press ALT while doing it and it will duplicate, showing a white "+" near the mouse cursor...
    My problem is, i can't reproduce this... I always got the plus sign.
    I tried using the "setCursor" method with something like that in the dragMoveEvent:

    if (event->keyboardModifiers() == modifier)
    		setCursor(Qt::DragCopyCursor);
    	else
    		setCursor(Qt::DragMoveCursor);
    

    It does not work, and worst, it does not change when I use the standard Qt::ArrowCursor...

    I then tried changing the drop action. The only way to remove that "+" icon it to set the action to IgnoreAction, which well, does do anything on drop...

    Anymore tried to do something like that ?



  • Hi,

    Maybe you can use

    QApplication::setOverrideCursor(Qt::DragCopyCursor);
    

    If you do so, when drag/drop event is done, DON'T USE IT WITH Qt::ArrowCursor. Instead, use the restore method:

    QApplication::restoreOverrideCursor();
    


  • Thanks for your reply :)

    Just tried that, doesn't work... Seems there is a thing with D&D icon management...

    BTW i use Qt 5.4.1 if it helps, i searched bug known bugs but nothing of this sort


  • Lifetime Qt Champion

    Hi,

    Are you creating the QDrag object yourself ?



  • @SGaist :
    Yes I do. I did not tried setting a pixmap to it though, i would prefer, if possible, the system icon instead of a custom one...



  • @jpalbertini
    Could you show us your code please? Or better, provide a minimal code to reproduce this behavior.


  • Moderators

    @jpalbertini said:

    I try to reproduce the behavior of the OSX finder: by default it moves files/directories but press ALT while doing it and it will duplicate, showing a white "+" near the mouse cursor...

    The possible drop actions are defined when creating/starting the QDrag. So may it be that you only set a single drop action there?
    These drop actions can then be chosen by the user by pressing the modifier keys on the keyboard during the drag.
    Additionally the target widget also can force a specific drop target to be set once you drag over it.



  • @ValentinMichelet
    the drag is done this way

    QDrag * drag = new QDrag(parentWidget());
    drag->start(Qt::CopyAction | Qt::MoveAction);
    

    Then the drop is here in the dragMoveEvent

    if (event->keyboardModifiers() == modifier)
    	event->setDropAction(Qt::MoveAction);
    else
    	event->setDropAction(Qt::IgnoreAction);
    

    Nothing else is tempering with the event...


  • Lifetime Qt Champion

    Can you share the complete implementation ?



  • @SGaist
    not all but here is most of it:

    Here ifs the code where we start the D&D operation:

    void QButtonSceneEditor::mouseMoveEvent(QMouseEvent* event)
    {
    	m_bIsMousePressProcessed = false;
    	if(isChecked())
    	{
    		if(!visibleRegion().contains(event->localPos().toPoint()) &&
    			event->buttons().testFlag(Qt::LeftButton))
    		{
    			dragDropManager()->addSceneButton(this);
    
    			QMimeData * mimeData = new QMimeData();
    			mimeData->setData(DVC_SCENE_MIME_DATA, 0);
    			QDrag * drag = new QDrag(parentWidget());
    			drag->setMimeData(mimeData);
    			drag->start(Qt::CopyAction | Qt::MoveAction);
    		}
    	}
    }
    

    It's an custom button we want to move internally into its parent

    void QSceneGroupEditor::dragMoveEvent(QDragMoveEvent * event)
    {
    	if (!event->mimeData()->hasFormat(DVC_SCENE_MIME_DATA))
    	{
    		event->ignore();
    		return;
    	}
    
    	QButtonScene* pScene = sceneAt(event->pos().x(), event->pos().y());
    	if (pScene)
    	{
    		bool bInTop = event->pos().y() <= pScene->geometry().center().y();
    		int iHover = m_lSceneButtons.indexOf(pScene);
    		for (int iDragged(0); iDragged < dragDropManager()->sceneButtonCount(); iDragged++)
    		{
    			QButtonScene* pButton = dragDropManager()->sceneButtonAt(iDragged);
    			if (pButton)
    			{
    				int iButton = m_lSceneButtons.indexOf(pButton);
    				if (m_lSceneButtons.contains(pButton))
    				{
    					if (iHover == iButton || (bInTop && iHover == iButton + 1) || (!bInTop && iHover == iButton - 1))
    					{
    						m_pLblSeparator->hide();
    						return;
    					}
    
    					m_pLblSeparator->show();
    					if (bInTop)
    						m_pLblSeparator->move(pScene->pos().x() - 8, pScene->pos().y() - 8);
    					else
    						m_pLblSeparator->move(pScene->pos().x() - 8, pScene->pos().y() + pScene->geometry().height() - 3);
    				}
    				else
    				{
    					m_pLblSeparator->show();
    					if (bInTop)
    						m_pLblSeparator->move(pScene->pos().x() - 8, pScene->pos().y() - 8);
    					else
    						m_pLblSeparator->move(pScene->pos().x() - 8, pScene->pos().y() + pScene->geometry().height() - 3);
    				}
    			}
    		}
    	}
    	else
    		m_pLblSeparator->hide();
    
    	Qt::KeyboardModifiers modifier = Qt::AltModifier;
    #if defined (Q_OS_MACX)
    	if (event->keyboardModifiers() == modifier)
    		event->setDropAction(Qt::MoveAction);
    	else
    		//event->setDropAction(Qt::IgnoreAction); // Works but, nothing happends...
    		event->setDropAction(Qt::CopyAction);
    #endif
    	m_pButAdd->setVisible(event->keyboardModifiers() == modifier);
    	event->accept();
    }
    

    Unless there is something I did not understand about the D&D and/or the mouse icon management, i can't change the mouse icon unless using the Qt::IgnoreAction...



  • Hum, nobody ?
    Maybe I should report a bug...


  • Lifetime Qt Champion

    Are you calling acceptProposedAction where appropriate ?



  • I believe that is OS specific.



  • Hi,

    I have the same problem, did you find a way to solve it?


Log in to reply
 

Looks like your connection to Qt Forum was lost, please wait while we try to reconnect.