Qt: Drag and Drop



  • Hallo,
    ich plage mich seit geraumer Zeit mit dem Drag and Drop von Dateien aus dem Windows-Explorer in meine Unterklasse von QTreeWidget. Das übernehmen der Filenamen in der Methode :: dropEvent(QDropEvent*) funktioniert einwandfrei, ich kann die Dateien über ein Signal ohne Probleme an einen Slot übertragen und dort weiter verarbeiten.
    Mein Problem ist, dass ich die Dateinamen irgendwie beim Bewegen des Mouse-Cursors in meinem TreeWidget anzeigen möchte. Es wird nur ein einfaches 'Drag'? ohne Inhalt angezeigt. Ich vermute, dass ich entweder in ::mouseMoveEvent(QMouseEvent*) oder ::dragMoveEvent(QDragMoveEvent*) tätig werden muss; aber wie?
    Schön, wenn einer helfen könnte.
    Gruß
    Helmut



  • Zeig halt deinen Code. Wahrscheinlich musst du im dragMoveEvent dasselbe machen, wie im dropEvent, aber ohne Code kann man nicht sagen, was du falsch machst.



  • Hallo Mechanics, danke für die Antwort.

    //-------------------------------------------------------------------
    void OOQtProjectTreeWidget::mouseMoveEvent (QMouseEvent * pEvent)
    {
    	SUPER::mouseMoveEvent( pEvent );
    }
    
    //-------------------------------------------------------------------
    void OOQtProjectTreeWidget::dragEnterEvent (QDragEnterEvent * pEvent)
    {
    	SUPER::dragEnterEvent( pEvent );
    	if ( pEvent->mimeData()->hasUrls() )
    	{
    	  pEvent->acceptProposedAction();
    	}
    	else
    	{
    		pEvent->ignore();
    	}
    }
    
    //-------------------------------------------------------------------
    void OOQtProjectTreeWidget::dragLeaveEvent (QDragLeaveEvent * pEvent)
    {
    	SUPER::dragLeaveEvent( pEvent );
    	pEvent->accept();
    }
    
    //-------------------------------------------------------------------
    void OOQtProjectTreeWidget::dragMoveEvent (QDragMoveEvent * pEvent)
    {
    	SUPER::dragMoveEvent( pEvent );
    	if ( pEvent->mimeData()->hasUrls() )
    	{
    	  pEvent->acceptProposedAction();
    
        // Das folgende hat keine Auswirkung auf die Anzeige des Drag-Mouse-Cursors.
        // Ich will, dass ein Text (später den 1. Dateinamen) angezeigt wird.
        QMimeData * t_pMimeData = new QMimeData;
        t_pMimeData->setText("Anzeige-Test1");
        t_pMimeData->setData("text/uri-list", "Anzeige-Test2");
        QDrag *     t_Drag = new QDrag(this);
        t_Drag->setMimeData(t_pMimeData);
    	}
    	else
    	{
    		pEvent->ignore();
    	}
    }
    
    //-------------------------------------------------------------------
    void OOQtProjectTreeWidget::dropEvent (QDropEvent * pEvent)
    {
    	if ( pEvent->mimeData()->hasUrls() )
    	{
    	  pEvent->accept();
    
    	  QStringList t_PathList;
    	  QList<QUrl> t_UrlList = pEvent->mimeData()->urls();
    
    	  for (int i = 0; i < t_UrlList.size() && i < 32; ++i)
    	  {
    			t_PathList.append(t_UrlList.at(i).toLocalFile());
    	  }
    	  // btw; lebt ggf. t_PathList lange genug??? Oder muss das auf dem Heap angelegt sein
        // um dann im 'fangenden' Slot zu killen. Was aber wenn mehrere Slots oder keiner?
        // Fragen über Fragen...
    	  emit this->Signal_FileNamesDroped( t_PathList );
    	}
    	else
    	{
    		pEvent->ignore();
    	}
    	SUPER::dropEvent( pEvent );
    }
    

    In meinem Editor sieht die Formatierung etwas besser aus.



  • Du hast eigentlich zwei Probleme, so wie ich das sehe. Was du im dropEvent machst, macht soweit Sinn. Das im dragMoveEvent irgendwie nicht.
    Da erstellst du selber ein neues QDrag und steckst da ein eigenes QMimeData Objekt rein. Warum? Mach doch dasselbe, wie im dropEvent, also pEvent->mimeData()->urls(). Damit bekommst du wieder die Dateinamen.

    Das nächste Problem ist, wie man sie darstellt. Ich weiß es ehrlich gesagt nicht auf Anhieb. Halte das auch eher für ein Gimmick. Die Dateinamen neben dem Cursor darzustellen würde schon irgendwie gehen, aber ich bezweifle, dass sich der Aufwand lohnt. Was ich mir auf jeden Fall vorstellen könnte, wäre eine Bitmap zu erstellen, die Daitenamen (oder was auch immer) reinzuzeichnen, daraus einen Cursor zu erstellen und den Cursor zu setzen. Vielleicht gibt es auch eine einfachere Möglichkeit. Noch einfacher wär auf jeden Fall, die Dateinamen irgendwo anders anzuzeigen, z.B. in der Statusleiste oder einem anderen Widget.



  • Hallo Mechanics,
    danke erstmal für Deine Hilfe, werde es mal mit dem Bitmap probieren. Kann ich aber erst ab Montag wieder. Wenn ich eine Lösung habe, werde ich mich nochmal melden.
    Gruß und schönes Restwochenende.
    Helmut Jakoby


Log in to reply