2012-07-04 16 views
5

Estoy implementando una vista y un modelo donde quiero admitir mover elementos internamente (arrastrando) y copiar elementos (presionando Ctrl mientras arrastro) He hecho todo lo que necesito hacer de acuerdo con las instrucciones. Configuré las funciones de mimo, implementé removeRows() y flags(). El problema es que cuando arrastro, de manera predeterminada se usa una operación de copia (obtengo el cursor de flecha con un signo más, y efectivamente copia el elemento creando uno nuevo en el modelo).Qt arrastrar/soltar: no se puede mover cuando la copia está habilitada (Ubuntu Gnome)

La única diferencia que puedo ver es la siguiente: si devuelvo solo Qt :: MoveAction en supportedDropActions(), solo se mueve. Si regreso (Qt :: CopyAction | Qt :: MoveAction), solo copia.

¿Alguna idea? Quiero que funcione como archivos en Nautilus (Gnome) o en el archivo de Windows Explorer: arrastrar mueve los iconos alrededor, ctrl + arrastrar los copia.

+0

El mismo problema ocurre en Windows, pero con 'Qt :: MoveAction' es la opción preferida. –

+0

Puedo publicar un código de ejemplo para demostrar el problema, si a alguien le gustaría. –

+0

Dado que esto no respondió mi pregunta al final, ¿quién siente que se merecen la recompensa? –

Respuesta

0

lo que si se intenta de esta manera Escribir una keyPressEvent y definir si se pulsa la tecla Ctrl o no '

keyPressEvent(QKeyEvent *e) 
    { 
     if(e->key() == Qt::Key_Control) 
      bControlKeyPressed = true; 
    } 
    keyReleaseEvent (QKeyEvent *e) 
    { 
     if(e->key() == Qt::Key_Control) 
      bControlKeyPressed = false; 
    } 

Y en el ratón pressEvent comprobar si se pulsa la tecla Ctrl

`mousePressEvent() 
{ 
    if (bControlKeyPressed) 
    //enable Qt::CopyAction 
else 
    //enable Qt::MoveAction 
}` 
+0

Una respuesta tan simple como esto sería ideal , pero Ubuntu/Windows simplemente ignora la acción especificada (y la acción predeterminada también). –

0

Esto es lo que haría:

habilite la acción de copia. Luego escucha drap & drop signals o anula los métodos virtuales (o lo que Qt ofrece, no lo verifiqué) y si la acción que quieres decir es move, elimina la fila "manualmente". Cuando se realiza una caída, guarde la acción que prefiera.

Si no hay manera de determinar la acción deseada de los datos de Qt, compruebe el estado de la tecla Ctrl y guarde un booleano que diga si se trata de copiar o mover. Ahora, cuando Qt señala que algo se cayó, verifica la acción que eliges y elimina la fila movida por ti mismo.

(Yo personalmente uso gtkmm, donde las obras de copia si-se-presiona Ctrl-pefectly)

+0

Esta solución funciona de alguna manera, pero tiene dos problemas: a) El icono de arrastre es incorrecto. b) Si se seleccionan varios elementos, al arrastrarlos entre ellos, se borran algunos y se copian otros. –

+0

Luego veo dos opciones para usted. 1) El enfoque de "acaba de deshacerse de él": establece el ícono de forma manual. Para una selección múltiple, maneje la gota usted mismo. Decida cómo mover/copiar cada nodo. Puede ser complicado, dependiendo de cómo Qt le permite acceder a los datos de arrastrar y soltar ... 2) el enfoque serio del ingeniero: descubra por qué esto no funciona como deberían. Qt es software gratuito, por lo que si hay un error, investigue si se puede resolver. Por lo tanto, usted hace una contribución a todos los usuarios de Qt y cualquier aplicación escrita con Qt. Y no se necesitarán soluciones alternativas. – cfa45ca55111016ee9269f0a52e771

+0

Si hay un problema con las partes internas de Windows, lo mejor que puede hacer es enviarles un correo electrónico. Windows es un software propietario, así que lo considero como su problema, no el mío o el tuyo, si D & D no funciona como debería. O agregue una solución temporal en su código, solo para Windows – cfa45ca55111016ee9269f0a52e771

1

Lo siento, no siguió respondiendo a esta pregunta cuando me encontré lo que estaba haciendo mal. El código que me estaba en mal estado en QAbstractItemView::startDrag():

if (d->defaultDropAction != Qt::IgnoreAction && (supportedActions & d->defaultDropAction)) 
     defaultDropAction = d->defaultDropAction; 
    else if (supportedActions & Qt::CopyAction && dragDropMode() != QAbstractItemView::InternalMove) 
     defaultDropAction = Qt::CopyAction; 

El problema es que no estaba poniendo el propiedad defaultDropAction en el widget como en setDefaultDropAction(Qt::MoveAction); Por lo tanto startDrag() no cumplía con CopyAction. Si la DefaultDropAction es Qt :: MoveAction, puede usar el teclado Ctrl para cambiar un arrastre en curso a una acción de copia, que es mi comportamiento deseado.

Me encanta Qt, pero seguro que hay muchas propiedades confusas y algo entrelazadas relacionadas con la función de arrastrar/soltar. Es fácil no obtener la combinación correcta de propiedades.

En pocas palabras: asegúrese de establecer la defaultDropAction a Qt :: MoveAction.

+0

Solo para dar un poco más de información, las propiedades que tuve que cambiar en listView son las siguientes: acceptDrops: true, dragEnabled: true, defaultDropAction: MoveAction (este fue el gran uno!), selectionMode: ExtendedSelection (también un comportamiento esperado de Windows Explorer pero no el predeterminado para QListView). También en el modelo: setSupportedDragActions (Qt :: CopyAction | Qt :: MoveAction) ;, return Qt :: CopyAction | Qt :: MoveAction en MyModel :: Model :: supportedDropActions(), agrega Qt :: ItemIsDragEnabled a MyModel :: flags(), implementa MyModel :: mimeTypes(), mimeData() y dropMimeData. ¡Espero que ayude! – Scott

+0

Esto significa que el error que estoy experimentando es realmente diferente al que experimentó. Se ve como un error de Qt en Windows. –

+0

D K, tengo curiosidad, ¿se trata de un Qt SDK (Creador) que está * generalmente * basado en mingw, o es Qt compilado con Visual Studio (que está basado en WinAPI?). Además, mi problema era que, con Copy como el comportamiento predeterminado, no podía lograr mover en absoluto, porque no hay ningún modificador de teclado para cambiar Copy to Move. Usted dice que tiene un problema con Move, por lo que no puede mantener presionada la tecla Ctrl y cambiarla a Copy? – Scott

Cuestiones relacionadas