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()
myremoveRows()
después dedropMimeData()
? -
removeRows()
llamoremoveRows()
manualmente endropMimeData()
? - 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 asetDragEnabled
ysetAcceptDrops
consecuencia.-
setDragEnabled
: habilita el mecanismo de arrastre incorporado -
setAcceptDrops
: habilita el mecanismo de caída incorporado
-
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ónQDrag
.
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
ysetData
. 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 deQt::CopyAction
soporte (Qt::CopyAction
de forma predeterminada). Tenga en cuenta que el usuario puede cambiar entre las diferentes acciones compatibles presionando algunas teclas. (shift
paraQt::MoveAction
ycontrol
paraQt::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.