qt drag-and-drop treeview

Arrastra y suelta en QTreeView, removeRows no llamado



drag-and-drop (3)

Tengo un problema con arrastrar y soltar en QTreeView :

Establecí el indicador en Qt::MoveAction y reimplement removeRows() , dropMimeData() y etc. en mi modelo. El modelo hereda QAbstractItemModel .

Cuando arrastro y suelte, mimeData() , dropMimeData() se llaman automáticamente, y también dropMimeData() llama a insertRows() automática. Pero removeRows() no se llama, por lo que el elemento arrastrado aún está activo. Busqué en Google, pero me dijeron que se llamaba automáticamente a sus removeRows() .

  • ¿Por qué no se removeRows() my removeRows() después de dropMimeData() ?
  • removeRows() llamo removeRows() manualmente en dropMimeData() ?
  • Si es así, ¿cómo puedo saber el QModelIndex anterior del inicio del arrastre?

Al iniciar el arrastre, en mimeData() , puedo guardar el índice en un miembro privado, pero parece que no es bueno.

Cualquier consejo sería apreciado.


Creo que sí, debes llamar a removeRows() desde dropMimeData() si Qt::DropAction es Qt::MoveAction , es decir, mueves completamente tu nodo de árbol de un lugar a otro.

WRT su segunda pregunta, puede crear sus datos mime personalizados en QAbstractItemModel::mimeData() y codificar allí la información inicial de los nodos arrastrados. Entonces, en la función dropMimeData() puede decodificar y usarla.


Tuve el mismo problema con mi modelo personalizado. Establecer dragDropOverwriteMode=false para ver mi problema resuelto.


Respuesta corta

Si todo está configurado correctamente, el objetivo no debe eliminar el elemento de origen, el iniciador del arrastre debe eliminar el elemento de origen si se realiza un Qt::MoveAction .

Configuración de la vista

QAbstractItemView (que es la clase base de QTreeView , QListView , QTableView , ...) implementa el inicio y el final de la operación startDrag en startDrag :

if (drag->exec(supportedActions, defaultDropAction) == Qt::MoveAction) d->clearOrRemove();

Por lo tanto, cuando la acción de soltar solicitada (devuelta por QDrag::exec ) es un Qt::MoveAction , el elemento se elimina automáticamente (o se borra según lo especificado por setDragDropOverwriteMode ).

Las opciones de configuración importantes de la vista son:

  • setDragDropMode : especifica si la vista debe aceptar arrastrar y / o soltar elementos externos o solo internos. Esta función llama a setDragEnabled y setAcceptDrops consecuencia.

  • setDragDropOverwriteMode : especifica si el elemento de origen debe ser eliminado (típico en una vista de árbol) o borrado (típico en una vista de tabla)

  • setDefaultDropAction : la acción de descarte predeterminada especificada al iniciar la operación QDrag .

Configuración del modelo

Además de la configuración de la vista, debe configurar su modelo correctamente.

  • Debe implementar la interfaz de edición de su modelo, es decir, insertRows , moveRows , moveRows y setData . Aunque puede no ser necesario implementarlos según su situación específica, es un buen enfoque implementarlos de todos modos para un modelo editable.

  • supportedDropActions : vuelva a implementar esta función para devolver las acciones de Qt::CopyAction soporte ( Qt::CopyAction de forma predeterminada). Tenga en cuenta que el usuario puede cambiar entre las diferentes acciones compatibles presionando algunas teclas. ( shift para Qt::MoveAction y control para Qt::CopyAction )

    • supportedDragActions : vuelva a implementar esta función si las acciones de arrastre admitidas son diferentes de las acciones de colocación admitidas.

Ejemplos

Buenos ejemplos son el código fuente de Qt en sí mismo. Las clases Q*Widget correspondientes (por ejemplo, QTreeWidget para QTreeView ) proporcionan implementaciones concretas de la vista y un modelo correspondiente.