Me gustaría poder anular la selección de elementos en mi QTreeView haciendo clic en una parte de QTreeView sin elementos, pero parece que no puedo encontrar nada de esto. Me gustaría interceptar un clic que no está en un elemento, pero el QTreeView no tiene una señal clicked
, por lo que no puedo encontrar la manera de hacerlo.¿Es posible anular la selección en un QTreeView haciendo clic en un elemento?
Respuesta
Esto es en realidad bastante simple (en PyQt):
class DeselectableTreeView(QtGui.QTreeView):
def mousePressEvent(self, event):
self.clearSelection()
QtGui.QTreeView.mousePressEvent(self, event)
Qt utiliza mousePressEvent
para emitir clicked
. Si borra la selección antes de enviar el evento, entonces, si se hace clic en un elemento, se seleccionará, de lo contrario, no se seleccionará nada. Muchas gracias a Patrice por ayudarme con esto :)
QTreeView
hereda de QAbstractView
(http://doc.qt.digia.com/4.6/qtreeview.html) que tiene una señal clicked
. El problema es que la señal se emite solo cuando el índice es válido, por lo que no puede lograr lo que quiere con esta señal.
Intente interceptar el mousePressEvent
en su lugar. En la función, puede encontrar dónde ha hecho clic el usuario y deseleccionar el elemento seleccionado si es necesario.
Puede intentar establecer un selection mode diferente para su artilugio. No sé si alguno de ellos cubre lo que parece que desea (selección única, pero no seleccionable).
No pude ver nada allí que lograra lo que quería, pero gracias de todos modos. – Skilldrick
clearSelection no funciona en mi caso. Estoy usando treeviews con un modo de selección individual. Esto es lo que he codificado:
class DeselectableTreeView : public QTreeView
{
public:
DeselectableTreeView(QWidget *parent) : QTreeView(parent) {}
virtual ~DeselectableTreeView() {}
private:
virtual void mousePressEvent(QMouseEvent *event)
{
QModelIndex item = indexAt(event->pos());
bool selected = selectionModel()->isSelected(item);
QTreeView::mousePressEvent(event);
if (selected)
selectionModel()->select(item, QItemSelectionModel::Deselect);
}
};
Esto funciona realmente bien.
Eric
@ Sobre la base de la solución de Eric, y ya que sólo se anula la selección de si se ha seleccionado el elemento se hace clic, esto es lo que ocurrió. Esta solución también funciona cuando hace clic en el área en blanco de la QTreeView
#ifndef DESELECTABLETREEVIEW_H
#define DESELECTABLETREEVIEW_H
#include "QTreeView"
#include "QMouseEvent"
#include "QDebug"
class DeselectableTreeView : public QTreeView
{
public:
DeselectableTreeView(QWidget *parent) : QTreeView(parent) {}
virtual ~DeselectableTreeView() {}
private:
virtual void mousePressEvent(QMouseEvent *event)
{
QModelIndex item = indexAt(event->pos());
bool selected = selectionModel()->isSelected(indexAt(event->pos()));
QTreeView::mousePressEvent(event);
if ((item.row() == -1 && item.column() == -1) || selected)
{
clearSelection();
const QModelIndex index;
selectionModel()->setCurrentIndex(index, QItemSelectionModel::Select);
}
}
};
#endif // DESELECTABLETREEVIEW_H
Yassir
+1 Esto era lo que estaba buscando. – aardvarkk
'indexAt' podría ser bastante caro, podría usar' item' en lugar de la segunda llamada. 'item.isValid()' es probablemente una mejor opción que comparar fila y columna a '-1'. Además, parece cambiar la selección si hace clic en los elementos? –
Para añadir a la respuesta @Skilldrick 's, si es necesario aplicar esto a una visión que ya ha sido ejemplarizado porque usted está utilizando Qt Designer, puede hacer algo como esto:
import new
def mousePressEvent(self, event):
self.clearSelection()
QtGui.QTableView.mousePressEvent(self, event)
self.ui.tableView.mousePressEvent = new.instancemethod(mousePressEvent, self.ui.tableView, None)
esto supone que su vista es self.ui.tableView
.
Gracias a esta respuesta: https://stackoverflow.com/a/1647616/1300519
En la respuesta por @Skilldrick, corremos el riesgo de enviar eventos superfluos. Si un elemento ya está seleccionado y lo estamos haciendo clic de nuevo, estamos levantando eventos deseleccionados y seleccionados. Según otros oyentes en su aplicación, esto podría no ser lo que desea.
La solución de @ eric-maeker solo anula la selección de un elemento si lo hacemos clic de nuevo mientras ya está seleccionado. Estrictamente hablando, esta no es la respuesta a la pregunta original, que fue cómo deseleccionar el elemento seleccionado al hacer clic en en otro lugar.
@ yassir-ennazk se acerca, pero como señala @ adrian-maire, la solución no es óptima. event->pos()
se evalúa dos veces. Además, el evento del mouse siempre se evalúa llamando al QTreeView::mousePressEvent
.
Esta es la solución que he encontrado, basada en las otras respuestas mencionadas anteriormente. Si estamos haciendo clic en un punto donde está presente otro elemento de vista de árbol, el nuevo elemento se selecciona reenviando el evento al TreeView
. Si no, estamos limpiando la selección.
Tenga en cuenta que esto también funciona con QTreeWidget
s.
virtual void mousePressEvent(QMouseEvent* event)
{
QModelIndex item = indexAt(event->pos());
if (item.isValid())
{
QTreeView::mousePressEvent(event);
}
else
{
clearSelection();
const QModelIndex index;
selectionModel()->setCurrentIndex(index, QItemSelectionModel::Select);
}
}
Lo único malo con la implementación predeterminada es que no borra la selección al hacer clic en un área en blanco de la vista. Así que simplemente verifique si el índice como pos es válido. Si no es así, llame a 'clearSelection()'. A continuación, llame incondicionalmente a la clase base 'mousePressEvent'. – ekhumoro
- 1. ¿Es posible anular un constructor en C#?
- 2. ¿Es posible anular un método estático en la clase derivada?
- 3. Selección lenta en QTreeView, ¿por qué?
- 4. ¿Es posible anular un campo de tipo?
- 5. Anular la selección de texto en un cuadro de texto
- 6. ¿Es posible anular un método no virtual?
- 7. Obteniendo el elemento seleccionado actualmente en QTreeView
- 8. ¿es posible anular un método en tiempo de ejecución?
- 9. Cómo anular la selección del texto de un cuadro combinado
- 10. Haciendo un JButton se puede hacer clic en un JTable
- 11. ¿Qué es "esto" en JavaScript haciendo clic?
- 12. jQuery arregle la orden li haciendo clic en un enlace
- 13. En Jquery, ¿cómo averiguas la 'eq' de un elemento de lo que se está haciendo clic?
- 14. Incrementar un número haciendo clic en un botón
- 15. ¿Forma superior, haciendo clic en "a través" posible?
- 16. ¿Es posible anular operadores en Java?
- 17. WPF DataGrid - anular la selección de elemento (s) seleccionado al hacer clic en un espacio en blanco en la cuadrícula de datos
- 18. JList - anule la selección al hacer clic en un elemento ya seleccionado
- 19. Haciendo clic en el token en NSTokenField
- 20. ¿Es posible enviar aEvent() un clic del mouse a un elemento <input type = text>?
- 21. Llamar a un método haciendo clic en un botón en un UIWebView
- 22. WPF: ¿cómo manejo un clic en un elemento de ListBox?
- 23. Pepino y carpincho, haciendo clic en un elemento de botón o sin vínculo
- 24. lista de WPF arrastre sin anular la selección
- 25. ¿Puedo deshabilitar la selección en un elemento UIPickerView específico?
- 26. ¿Cómo aceptar una llamada entrante haciendo clic en un botón?
- 27. ¿Es posible reemplazar un botón asp: con un elemento HTML
- 28. ¿Cómo deseleccionar un elemento en un cuadro de selección?
- 29. Haciendo un control "transparente" para hacer clic en eventos
- 30. Java Abrir una nueva ventana haciendo clic en un botón
Gracias. ¡He agregado mi propia respuesta pero +1 porque me ayudaste a llegar! – Skilldrick
De nada Skilldrick –