QRangeModel Class
QRangeModel implementa QAbstractItemModel para cualquier rango C++. Más...
| Cabecera: | #include <QRangeModel> |
| CMake: | find_package(Qt6 REQUIRED COMPONENTS Core)target_link_libraries(mytarget PRIVATE Qt6::Core) |
| qmake: | QT += core |
| Desde: | Qt 6.10 |
| Hereda: | QAbstractItemModel |
Nota: Todas las funciones de esta clase son reentrantes.
Tipos Públicos
(since 6.11) struct | ItemAccess |
(since 6.10) struct | RowOptions |
(since 6.11) enum class | AutoConnectPolicy { None, Full, OnRead } |
| enum class | RowCategory { Default, MultiRoleItem } |
Propiedades
(since 6.11)autoConnectPolicy : AutoConnectPolicy- roleNames : QHash<int, QByteArray>
Funciones públicas
| QRangeModel(Range &&range, QObject *parent = nullptr) | |
| QRangeModel(Range &&range, Protocol &&protocol, QObject *parent = nullptr) | |
| virtual | ~QRangeModel() override |
| QRangeModel::AutoConnectPolicy | autoConnectPolicy() const |
| void | resetRoleNames() |
| void | setAutoConnectPolicy(QRangeModel::AutoConnectPolicy policy) |
| void | setRoleNames(const QHash<int, QByteArray> &names) |
Funciones públicas reimplementadas
| virtual QModelIndex | buddy(const QModelIndex &index) const override |
| virtual bool | canDropMimeData(const QMimeData *data, Qt::DropAction action, int row, int column, const QModelIndex &parent) const override |
| virtual bool | canFetchMore(const QModelIndex &parent) const override |
| virtual bool | clearItemData(const QModelIndex &index) override |
| virtual int | columnCount(const QModelIndex &parent = {}) const override |
| virtual QVariant | data(const QModelIndex &index, int role = Qt::DisplayRole) const override |
| virtual bool | dropMimeData(const QMimeData *data, Qt::DropAction action, int row, int column, const QModelIndex &parent) override |
| virtual void | fetchMore(const QModelIndex &parent) override |
| virtual Qt::ItemFlags | flags(const QModelIndex &index) const override |
| virtual bool | hasChildren(const QModelIndex &parent = QModelIndex()) const override |
| virtual QVariant | headerData(int section, Qt::Orientation orientation, int role = Qt::DisplayRole) const override |
| virtual QModelIndex | index(int row, int column, const QModelIndex &parent = {}) const override |
| virtual bool | insertColumns(int column, int count, const QModelIndex &parent = {}) override |
| virtual bool | insertRows(int row, int count, const QModelIndex &parent = {}) override |
| virtual QMap<int, QVariant> | itemData(const QModelIndex &index) const override |
| virtual QModelIndexList | match(const QModelIndex &start, int role, const QVariant &value, int hits, Qt::MatchFlags flags) const override |
| virtual QMimeData * | mimeData(const QModelIndexList &indexes) const override |
| virtual QStringList | mimeTypes() const override |
| virtual bool | moveColumns(const QModelIndex &sourceParent, int sourceColumn, int count, const QModelIndex &destinationParent, int destinationColumn) override |
| virtual bool | moveRows(const QModelIndex &sourceParent, int sourceRow, int count, const QModelIndex &destinationParent, int destinationRow) override |
| virtual void | multiData(const QModelIndex &index, QModelRoleDataSpan roleDataSpan) const override |
| virtual QModelIndex | parent(const QModelIndex &child) const override |
| virtual bool | removeColumns(int column, int count, const QModelIndex &parent = {}) override |
| virtual bool | removeRows(int row, int count, const QModelIndex &parent = {}) override |
| virtual QHash<int, QByteArray> | roleNames() const override |
| virtual int | rowCount(const QModelIndex &parent = {}) const override |
| virtual bool | setData(const QModelIndex &index, const QVariant &data, int role = Qt::EditRole) override |
| virtual bool | setHeaderData(int section, Qt::Orientation orientation, const QVariant &data, int role = Qt::EditRole) override |
| virtual bool | setItemData(const QModelIndex &index, const QMap<int, QVariant> &data) override |
| virtual QModelIndex | sibling(int row, int column, const QModelIndex &index) const override |
| virtual void | sort(int column, Qt::SortOrder order = Qt::AscendingOrder) override |
| virtual QSize | span(const QModelIndex &index) const override |
| virtual Qt::DropActions | supportedDragActions() const override |
| virtual Qt::DropActions | supportedDropActions() const override |
Señales
| void | autoConnectPolicyChanged(QRangeModel::AutoConnectPolicy policy) |
| void | roleNamesChanged() |
Funciones protegidas reimplementadas
| virtual bool | event(QEvent *event) override |
| virtual bool | eventFilter(QObject *object, QEvent *event) override |
Ranuras protegidas
| virtual void | resetInternalData() override |
Descripción detallada
QRangeModel puede hacer que los datos de cualquier tipo C++ secuencialmente iterable estén disponibles para el framework modelo/vista de Qt. Esto facilita la visualización de estructuras de datos existentes en las vistas de elementos Qt Widgets y Qt Quick, y permite al usuario de la aplicación manipular los datos utilizando una interfaz gráfica de usuario.
Para utilizar QRangeModel, hay que instanciarlo con un rango C++ y establecerlo como modelo de una o más vistas:
std::array<int, 5> numbers = {1, 2, 3, 4, 5}; QRangeModel model(numbers); listView.setModel(&model);
Construcción del modelo
El rango puede ser cualquier tipo C++ para el que estén implementados los métodos estándar std::begin y std::end, y para el que el tipo de iterador devuelto satisfaga std::forward_iterator. Algunas operaciones del modelo funcionarán mejor si std::size está disponible y si el iterador cumple std::random_access_iterator.
El rango debe proporcionarse al construir el modelo y puede proporcionarse por valor, envoltura de referencia o puntero. La forma en que se construyó el modelo define si los cambios a través de la API del modelo modificarán los datos originales. Utilice QRangeModelAdapter para construir implícitamente un modelo y disponer al mismo tiempo de un acceso directo, seguro y cómodo al modelo como rango.
Cuando se construye por valor, el modelo hace una copia del rango, y las API de QAbstractItemModel que modifican el modelo, como setData() o insertRows(), no afectan al rango original.
QRangeModel model(numbers);Los cambios realizados en los datos pueden controlarse conectándose a las señales emitidas por el modelo, como dataChanged().
Para que las modificaciones del modelo afecten al rango original, proporcione el rango bien mediante un puntero
QRangeModel model(&numbers);
o a través de una envoltura de referencia:
QRangeModel model(std::ref(numbers));
En este caso, las API de QAbstractItemModel que modifican el modelo también modifican el rango. Los métodos que modifican la estructura del rango, como insertRows() o removeColumns(), utilizan las API contenedoras estándar de C++ resize(), insert(), erase(), además de desreferenciar un iterador mutante para establecer o borrar los datos.
Nota: Una vez que el modelo ha sido construido y pasado a una vista, el rango sobre el que opera el modelo no debe ser modificado directamente. Las vistas sobre el modelo no serían informadas de los cambios, y es probable que los cambios estructurales corrompan las instancias de QPersistentModelIndex que el modelo mantiene. Utilice QRangeModelAdapter para interactuar de forma segura con el rango subyacente mientras mantiene el modelo actualizado.
El invocador debe asegurarse de que el tiempo de vida del rango excede el tiempo de vida del modelo.
Utilice punteros inteligentes para asegurarse de que el rango sólo se elimina cuando todos los clientes han terminado con él.
auto shared_numbers = std::make_shared<std::vector<int>>(numbers); QRangeModel model(shared_numbers);
QRangeModel admite tanto punteros compartidos como punteros únicos.
Sólo lectura o mutable
Para rangos que son objetos const, para los que el acceso siempre produce valores constantes, o donde las APIs contenedoras requeridas no están disponibles, QRangeModel implementa APIs de acceso de escritura para no hacer nada y devolver false. En el ejemplo que utiliza std::array, el modelo no puede añadir ni eliminar filas, ya que el número de entradas de una matriz C++ es fijo. Pero los valores pueden cambiarse utilizando setData(), y el usuario puede activar la edición de los valores en la vista de lista. Al hacer el array const, los valores también pasan a ser de sólo lectura.
const std::array<int, 5> numbers = {1, 2, 3, 4, 5};
Los valores también son de sólo lectura si el tipo de elemento es const, como en
std::array<const int, 5> numbers = {1, 2, 3, 4, 5};
En los ejemplos anteriores utilizando std::vector, el modelo puede añadir o eliminar filas, y los datos pueden ser modificados. Si se pasa el rango como una referencia constante, el modelo será de sólo lectura.
QRangeModel model(std::cref(numbers));
Nota: Si los valores del rango son constantes, tampoco es posible eliminar o insertar columnas y filas a través de la API QAbstractItemModel. Para un control más granular, implemente the C++ tuple protocol.
Filas y columnas
Los elementos del rango se interpretan como filas del modelo. Dependiendo del tipo de estos elementos de fila, QRangeModel expone el rango como una lista, una tabla o un árbol.
Si los elementos de la fila son valores simples, el rango se representa como una lista.
QList<int> numbers = {1, 2, 3, 4, 5}; QRangeModel model(numbers); // columnCount() == 1 QListView listView; listView.setModel(&model);
Si el tipo de los elementos de fila es un rango iterable, como un vector, una lista o una matriz, el rango se representa como una tabla.
std::vector<std::vector<int>> gridOfNumbers = { {1, 2, 3, 4, 5}, {6, 7, 8, 9, 10}, {11, 12, 13, 14, 15}, }; QRangeModel model(&gridOfNumbers); // columnCount() == 5 QTableView tableView; tableView.setModel(&model);
Si el tipo de fila proporciona las API contenedoras estándar de C++ resize(), insert(), erase(), entonces se pueden añadir y eliminar columnas a través de insertColumns() y removeColumns(). Todas las filas deben tener el mismo número de columnas.
Estructuras y gadgets como filas
Si el tipo de fila implementa the C++ tuple protocol, entonces el rango se representa como una tabla con un número fijo de columnas.
using TableRow = std::tuple<int, QString>; QList<TableRow> numberNames = { {1, "one"}, {2, "two"}, {3, "three"} }; QRangeModel model(&numberNames); // columnCount() == 2 QTableView tableView; tableView.setModel(&model);
Una alternativa más sencilla y flexible a la implementación del protocolo de tuplas para un tipo C++ es utilizar el sistema de metaobjetos de Qt para declarar un tipo con propiedades. Este puede ser un tipo de valor que se declara como gadget, o una subclase de QObject.
class Book { Q_GADGET Q_PROPERTY(QString title READ title) Q_PROPERTY(QString author READ author) Q_PROPERTY(QString summary MEMBER m_summary) Q_PROPERTY(int rating READ rating WRITE setRating) public: Book(const QString &title, const QString &author); // C++ rule of 0: destructor, as well as copy/move operations // provided by the compiler. // read-only properties QString title() const { return m_title; } QString author() const { return m_author; } // read/writable property with input validation int rating() const { return m_rating; } void setRating(int rating) { m_rating = qBound(0, rating, 5); } private: QString m_title; QString m_author; QString m_summary; int m_rating = 0; };
El uso de subclases de QObject permite que las propiedades sean vinculables, o que tengan señales de notificación de cambios. Sin embargo, el uso de instancias de QObject para los elementos tiene una sobrecarga de memoria significativa.
Utilizar gadgets u objetos Qt es más cómodo y puede ser más flexible que implementar el protocolo de tuplas. Estos tipos también son directamente accesibles desde QML. Sin embargo, el acceso a través del sistema de propiedades conlleva cierta sobrecarga en tiempo de ejecución. En el caso de los modelos de rendimiento crítico, se recomienda implementar el protocolo de tupla para generar el código de acceso en tiempo de compilación.
Elementos polivalentes
El tipo de los elementos sobre los que operan las implementaciones de data(), setData(), clearItemData(), etc. puede ser el mismo en todo el modelo, como en el ejemplo anterior de gridOfNumbers. Pero el rango también puede tener diferentes tipos de elementos para diferentes columnas, como en el caso de numberNames.
Por defecto, el valor se utiliza para los roles Qt::DisplayRole y Qt::EditRole. La mayoría de las vistas esperan que el valor sea convertible to and from a QString (pero un delegado personalizado puede proporcionar más flexibilidad).
Contenedores asociativos con varios roles
Si el elemento es un contenedor asociativo que utiliza int, Qt::ItemDataRole, o QString como tipo clave, y QVariant como tipo mapeado, entonces QRangeModel interpreta ese contenedor como el almacenamiento de los datos para múltiples roles. Las funciones data() y setData() devuelven y modifican el valor mapeado en el contenedor, y setItemData() modifica todos los valores proporcionados, itemData() devuelve todos los valores almacenados, y clearItemData() borra todo el contenedor.
using ColorEntry = QMap<Qt::ItemDataRole, QVariant>; const QStringList colorNames = QColor::colorNames(); QList<ColorEntry> colors; colors.reserve(colorNames.size()); for (const QString &name : colorNames) { const QColor color = QColor::fromString(name); colors << ColorEntry{{Qt::DisplayRole, name}, {Qt::DecorationRole, color}, {Qt::ToolTipRole, color.name()}}; } QRangeModel colorModel(colors); QListView list; list.setModel(&colorModel);
El tipo de datos más eficiente para utilizar como clave es Qt::ItemDataRole o int. Cuando se utiliza int, itemData() devuelve el contenedor tal cual, y no tiene que crear una copia de los datos.
Gadgets y objetos como elementos con múltiples funciones
Los gadgets y los tipos QObject también pueden representarse como elementos multi-función. Las propiedades de estos elementos se utilizarán para el rol con el que coincida name of a role. Si todos los elementos contienen el mismo tipo de gadget o QObject, la implementación de roleNames() en QRangeModel devolverá la lista de propiedades de ese tipo.
class ColorEntry { Q_GADGET Q_PROPERTY(QString display MEMBER m_colorName) Q_PROPERTY(QColor decoration READ decoration) Q_PROPERTY(QString toolTip READ toolTip) public: ColorEntry(const QString &color = {}) : m_colorName(color) {} QColor decoration() const { return QColor::fromString(m_colorName); } QString toolTip() const { return QColor::fromString(m_colorName).name(); } private: QString m_colorName; };
Cuando se utiliza en una tabla, ésta es la representación por defecto para los gadgets:
QList<QList<ColorEntry>> colorTable; // ... QRangeModel colorModel(colorTable); QTableView table; table.setModel(&colorModel);
Sin embargo, cuando se utilizan en una lista, estos tipos se representan por defecto como filas de varias columnas, con cada propiedad representada como una columna independiente. Para forzar que un gadget se represente como un elemento multirol en una lista, declare el gadget como un tipo multirol especializando QRoleModel::RowOptions, con una variable miembro static constexpr auto rowCategory establecida en MultiRoleItem.
class ColorEntry { Q_GADGET Q_PROPERTY(QString display MEMBER m_colorName) Q_PROPERTY(QColor decoration READ decoration) Q_PROPERTY(QString toolTip READ toolTip) public: ... }; template <> struct QRangeModel::RowOptions<ColorEntry> { static constexpr auto rowCategory = QRangeModel::RowCategory::MultiRoleItem; };
También puede envolver estos tipos en una tupla de un solo elemento, convirtiendo la lista en una tabla con una sola columna:
const QStringList colorNames = QColor::colorNames(); QList<std::tuple<ColorEntry>> colors; // ... QRangeModel colorModel(colors); QListView list; list.setModel(&colorModel);
En este caso, tenga en cuenta que para acceder directamente a los elementos de los datos de la lista es necesario utilizar std::get:
ColorEntry firstEntry = std::get<0>(colors.at(0));
o alternativamente un enlace estructurado:
auto [firstEntry] = colors.at(0);
Filas como valores o punteros
En los ejemplos anteriores, siempre hemos utilizado QRangeModel con rangos que contienen valores. QRangeModel también puede operar con rangos que contengan punteros, incluidos los punteros inteligentes. Esto permite a QRangeModel operar con rangos de tipos polimorfos, como las subclases de QObject.
class Entry : public QObject { Q_OBJECT Q_PROPERTY(QString display READ display WRITE setDisplay NOTIFY displayChanged) Q_PROPERTY(QIcon decoration READ decoration WRITE setDecoration NOTIFY decorationChanged) Q_PROPERTY(QString toolTip READ toolTip WRITE setToolTip NOTIFY toolTipChanged) public: Entry() = default; QString display() const { return m_display; } void setDisplay(const QString &display) { if (m_display == display) return; m_display = display; emit displayChanged(m_display); } signals: void displayChanged(const QString &); ... }; std::vector<std::shared_ptr<Entry>> entries = { ... }; QRangeModel model(std::ref(entries)); QListView listView; listView.setModel(&model);
Al igual que con los valores, el tipo de la fila define si el rango se representa como una lista, tabla o árbol. Las filas que son QObjects presentarán cada propiedad como una columna, a menos que la plantilla QRangeModel::RowOptions esté especializada para declarar el tipo como un elemento polimorfo.
template <> struct QRangeModel::RowOptions<Entry> { static constexpr auto rowCategory = QRangeModel::RowCategory::MultiRoleItem; }; std::vector<std::shared_ptr<Entry>> entries = { std::make_shared<Entry>(), ... }; QRangeModel model(std::ref(entries));
Nota: Si el rango contiene punteros en bruto, entonces tienes que construir QRangeModel a partir de un puntero o envoltorio de referencia del rango. De lo contrario, la propiedad de los datos se vuelve ambigua, y una copia del rango seguiría operando sobre los mismos datos reales de la fila, lo que provocaría efectos secundarios inesperados.
Subclase de QRangeModel
Subclasificar QRangeModel permite añadir APIs prácticas que tienen en cuenta el tipo de datos y la estructura del rango.
class NumbersModel : public QRangeModel { std::vector<int> m_numbers; public: NumbersModel(const std::vector<int> &numbers) : QRangeModel(std::ref(m_numbers)) , m_numbers(numbers) { }
Al hacerlo, añada el rango como un miembro privado y llame al constructor de QRangeModel con una envoltura de referencia o un puntero a ese miembro. Esto encapsula adecuadamente los datos y evita el acceso directo.
void setNumber(int idx, int number) { setData(index(idx, 0), QVariant::fromValue(number)); } int number(int idx) const { return m_numbers.at(idx); } };
Añada funciones miembro para proporcionar un acceso seguro a los datos, utilizando la API QAbstractItemModel para realizar cualquier operación que modifique el rango. El acceso de sólo lectura puede operar directamente sobre la estructura de datos.
Árboles de datos
QRangeModel puede representar una estructura de datos como un modelo de árbol. Una estructura de datos en forma de árbol debe ser homomórfica: en todos los niveles del árbol, la lista de filas secundarias debe utilizar exactamente la misma representación que el propio árbol. Además, el tipo de fila debe tener un tamaño estático: un tipo gadget o QObject, o un tipo que implemente the C++ tuple protocol.
Para representar estos datos como un árbol, QRangeModel tiene que ser capaz de recorrer la estructura de datos: para cualquier fila dada, el modelo tiene que ser capaz de recuperar la fila padre, y el tramo opcional de los hijos. Estas funciones transversales pueden proporcionarse implícitamente a través del tipo de fila, o a través de un tipo de protocolo explícito.
Protocolo implícito de recorrido del árbol
class TreeRow; using Tree = std::vector<TreeRow>;
El árbol en sí es un vector de valores TreeRow. Véase Tree Rows as pointers or values para las consideraciones sobre si utilizar valores o punteros de elementos para las filas.
class TreeRow { Q_GADGET // properties TreeRow *m_parent; std::optional<Tree> m_children; public: TreeRow() = default; // rule of 0: copy, move, and destructor implicitly defaulted
La clase de fila puede ser de cualquier tipo de tamaño fijo descrito anteriormente: un tipo que implemente el protocolo de tupla, un gadget o un QObject. En este ejemplo, utilizamos un gadget.
Cada elemento de fila necesita mantener un puntero a la fila padre, así como un rango opcional de filas hijas. Ese rango debe ser idéntico a la estructura de rangos utilizada para el propio árbol.
Hacer que el tipo de fila por defecto sea construible es opcional, y permite al modelo construir nuevos elementos de datos de fila, por ejemplo en las implementaciones insertRow() o moveRows().
// tree traversal protocol implementation const TreeRow *parentRow() const { return m_parent; } const std::optional<Tree> &childRows() const { return m_children; }
El protocolo de recorrido del árbol puede entonces implementarse como funciones miembro del tipo de datos fila. Una función const parentRow() tiene que devolver un puntero a un elemento de fila; y la función childRows() tiene que devolver una referencia a una const std::optional que pueda contener el rango hijo opcional.
Estas dos funciones son suficientes para que el modelo navegue por el árbol como una estructura de datos de sólo lectura. Para permitir al usuario editar datos en una vista, y al modelo implementar APIs de modelo mutante como insertRows(), removeRows(), y moveRows(), tenemos que implementar funciones adicionales para el acceso de escritura:
void setParentRow(TreeRow *parent) { m_parent = parent; } std::optional<Tree> &childRows() { return m_children; }
El modelo llama a la función setParentRow() y a la sobrecarga mutable childRows() para mover o insertar filas en una rama de árbol existente, y para actualizar el puntero padre en caso de que el valor antiguo haya dejado de ser válido. La sobrecarga no-const de childRows() proporciona además acceso de escritura a los datos de la fila.
Nota: El modelo realiza el establecimiento del padre de una fila, la eliminación de esa fila del antiguo padre, y su adición a la lista de hijos del nuevo padre, como pasos separados. De este modo, la interfaz del protocolo es más pequeña.
...
// Helper to assembly a tree of rows, not used by QRangeModel
template <typename ...Args>
TreeRow &addChild(Args &&...args)
{
if (!m_children)
m_children.emplace(Tree{});
auto &child = m_children->emplace_back(std::forward<Args>(args)...);
child.m_parent = this;
return child;
}
};El resto de la implementación de la clase no es relevante para el modelo, pero un ayudante de addChild() nos proporciona una forma conveniente de construir el estado inicial del árbol.
Tree tree = { {"..."}, {"..."}, {"..."}, }; // each toplevel row has three children tree[0].addChild("..."); tree[0].addChild("..."); tree[0].addChild("..."); tree[1].addChild("..."); tree[1].addChild("..."); tree[1].addChild("..."); tree[2].addChild("..."); tree[2].addChild("..."); tree[2].addChild("...");
Un QRangeModel instanciado con una instancia de dicho rango representará los datos como un árbol.
// instantiate the model with a pointer to the tree, not a copy! QRangeModel model(&tree); QTreeView view; view.setModel(&model);
Protocolo de recorrido del árbol en una clase separada
El protocolo de recorrido del árbol también puede implementarse en una clase independiente.
struct TreeTraversal { TreeRow newRow() const { return TreeRow{}; } const TreeRow *parentRow(const TreeRow &row) const { return row.m_parent; } void setParentRow(TreeRow &row, TreeRow *parent) const { row.m_parent = parent; } const std::optional<Tree> &childRows(const TreeRow &row) const { return row.m_children; } std::optional<Tree> &childRows(TreeRow &row) const { return row.m_children; } };
Pase una instancia de esta implementación de protocolo al constructor de QRangeModel:
QRangeModel model(&tree, TreeTraversal{});
Filas de árbol como punteros o valores
El tipo de fila del rango de datos puede ser un valor o un puntero. En el código anterior hemos estado utilizando las filas del árbol como valores en un vector, lo que evita que tengamos que ocuparnos de la gestión explícita de la memoria. Sin embargo, un vector como bloque contiguo de memoria invalida todos los iteradores y referencias cuando tiene que reasignar el almacenamiento, o cuando inserta o elimina elementos. Esto afecta al puntero al elemento padre, que es la ubicación de la fila padre dentro del vector. Asegurarse de que este elemento padre (y las instancias de QPersistentModelIndex que hacen referencia a elementos dentro de él) sigue siendo válido puede incurrir en una considerable sobrecarga de rendimiento. La implementación de QRangeModel tiene que asumir que todas las referencias al rango se vuelven inválidas cuando se modifica el rango.
Alternativamente, también podemos utilizar un rango de punteros de fila como tipo de árbol:
struct TreeRow; using Tree = std::vector<TreeRow *>;
En este caso, tenemos que asignar todas las instancias TreeRow explícitamente utilizando el operador new, e implementar el destructor para delete todos los elementos del vector de hijos.
struct TreeRow { Q_GADGETpublic: TreeRow(const QString &valor = {}) : m_valor(valor) {} ~TreeRow() { if (m_hijos) qDeleteAll(*m_children); ¡} // move-onlyTreeRow(TreeRow &&) = default; TreeRow &operator=(TreeRow &&) = default; // helper to populate template <typename ...Args>TreeRow *addChild(Args &&...args) { if (!m_children) m_children.emplace(Tree{}); auto *child = m_children->emplace_back(new TreeRow(std::forward<Args>(args)...)); child->m_parent = this; return child; }private: friend struct TreeTraversal; QString m_value; std::optional<Tree> m_children; TreeRow *m_parent = nullptr; }; Tree tree = { new TreeRow("1"), new TreeRow("2"), new TreeRow("3"), new TreeRow("4"),}; tree[0]->addChild("1.1"); tree[1]->addChild("2.1"); tree[2]->addChild("3.1")->addChild("3.1.1"); tree[3]->addChild("4.1");
Antes de que podamos construir un modelo que represente estos datos como un árbol, necesitamos implementar también el protocolo de recorrido del árbol.
struct TreeTraversal { TreeRow *newRow() const { return new TreeRow; } void deleteRow(TreeRow *row) { delete row; } const TreeRow *parentRow(const TreeRow &row) const { return row.m_parent; } void setParentRow(TreeRow &row, TreeRow *parent) { row.m_parent = parent; } const std::optional<Tree> &childRows(const TreeRow &row) const { return row.m_children; } std::optional<Tree> &childRows(TreeRow &row) { return row.m_children; } };
Una implementación explícita del protocolo para árboles mutables de punteros tiene que proporcionar dos funciones miembro adicionales, newRow() y deleteRow(RowType *).
int main(int argc, char **argv) { QApplication app(argc, argv); Tree tree = make_tree_of_pointers(); QRangeModel model(std::move(tree), TreeTraversal{}); QTreeView treeView; treeView.setModel(&model); treeView.show(); return app.exec(); }
El modelo llamará a esas funciones cuando cree nuevas filas en insertRows(), y cuando elimine filas en removeRows(). Además, si el modelo es propietario de los datos, también borrará todas las filas de nivel superior al destruirlas. Observa cómo en este ejemplo, movemos el árbol dentro del modelo, por lo que ya no debemos realizar ninguna operación sobre él. QRangeModel, cuando se construye moviendo datos de árbol con punteros de fila en él, tomará la propiedad de los datos, y eliminará los punteros de fila en su destructor.
El uso de punteros como filas conlleva cierta sobrecarga en la asignación y gestión de memoria. Sin embargo, las referencias a los elementos de la fila permanecen estables, incluso cuando se mueven en el rango, o cuando el rango se reasigna. Esto puede reducir significativamente el coste de realizar modificaciones en la estructura del modelo cuando se utiliza insertRows(), removeRows(), o moveRows().
Cada opción tiene diferentes compensaciones de rendimiento y sobrecarga de memoria. La mejor opción depende del caso de uso exacto y de la estructura de datos utilizada.
El protocolo de tuplas de C
Como se ha visto en el ejemplo anterior de numberNames, el tipo de fila puede ser una tupla y, de hecho, cualquier tipo que implemente el protocolo de tuplas. Este protocolo se implementa especializando std::tuple_size y std::tuple_element, y sobrecargando la función no cualificada get. Hazlo para tu tipo de fila personalizado para que los datos estructurados existentes estén disponibles para el marco modelo/vista en Qt.
struct Book { QString title; QString author; QString summary; int rating = 0; template <size_t I, typename T> requires ((I <= 3) && std::is_same_v<std::remove_cvref_t<T>, Book>) friend inline decltype(auto) get(T &&book) { if constexpr (I == 0) return std::as_const(book.title); else if constexpr (I == 1) return std::as_const(book.author); else if constexpr (I == 2) return std::forward_like<T>(book.summary); else if constexpr (I == 3) return std::forward_like<T>(book.rating); } }; namespace std { template <> struct tuple_size<Book> : std::integral_constant<size_t, 4> {}; template <size_t I> struct tuple_element<I, Book> { using type = decltype(get<I>(std::declval<Book>())); }; }
En la implementación anterior, los valores title y author del tipo Book se devuelven como const, por lo que el modelo marca los elementos de esas dos columnas como de sólo lectura. El usuario no podrá activar la edición, y setData() no hace nada y devuelve false. Para summary y rating la implementación devuelve la misma categoría de valor que el libro, por lo que cuando se llama a get con una referencia mutable a una Book, entonces devolverá una referencia mutable de la variable respectiva. El modelo hace que esas columnas sean editables, tanto para el usuario como para el acceso programático.
Nota: La implementación de get requiere C++23.
Consideraciones sobre compatibilidad binaria
QRangeModel no es una clase de plantilla. Pasar instancias de QRangeModel (por puntero o referencia, como con todas las clases QObject ) a través de APIs de bibliotecas, o almacenar QRangeModel por valor en una clase pública de una biblioteca, es seguro.
Sin embargo, el constructor de QRangeModel es una plantilla e inline, y la implementación interna especializada en el tipo de rango sobre el que opera el modelo se instancia en el constructor. No debería llamar al constructor en una implementación en línea de una API de biblioteca. Da lugar a violaciones de ODR, y podría romper la compatibilidad binaria de esa biblioteca si la versión de Qt con la que se construye es diferente de la versión de Qt con la que se construye una aplicación que utiliza esa biblioteca.
Véase también Programación Modelo/Vista.
Documentación de tipos de miembros
[since 6.11] enum class QRangeModel::AutoConnectPolicy
Este enum define si y cuando QRangeModel auto-conecta las señales de cambio de las propiedades a la señal dataChanged() del modelo. Sólo se conectan las propiedades que coinciden con una de las role names.
| Constante | Valor | Descripción |
|---|---|---|
QRangeModel::AutoConnectPolicy::None | 0 | No se realizan conexiones automáticamente. |
QRangeModel::AutoConnectPolicy::Full | 1 | Las señales de todas las propiedades relevantes se conectan automáticamente, para todos los elementos de QObject. Esto incluye los elementos de QObject que se añaden a filas y columnas recién insertadas. |
QRangeModel::AutoConnectPolicy::OnRead | 2 | Las señales de las propiedades relevantes se conectan la primera vez que el modelo lee la propiedad. |
La sobrecarga de memoria que supone realizar conexiones automáticas puede ser considerable. Una conexión automática completa no requiere ninguna contabilidad además de la conexión en sí, pero cada conexión ocupa memoria, y conectar todas las propiedades de todos los objetos puede ser muy costoso, especialmente si sólo van a cambiar unas pocas propiedades de un subconjunto de objetos.
La política de conexión OnRead no se conectará a objetos o propiedades que nunca se lean (por ejemplo, que nunca se representen en una vista), pero recordar qué conexiones se han realizado requiere cierta sobrecarga de contabilidad y un crecimiento impredecible de la memoria a lo largo del tiempo. Por ejemplo, desplazarse por una larga lista de elementos puede dar lugar fácilmente a miles de nuevas conexiones.
Este enum se introdujo en Qt 6.11.
Véase también autoConnectPolicy y roleNames().
enum class QRangeModel::RowCategory
Este enum describe cómo QRangeModel debe presentar los elementos del rango con el que se construyó.
| Constante | Valor | Descripción |
|---|---|---|
QRangeModel::RowCategory::Default | 0 | QRangeModel decide cómo presentar las filas. |
QRangeModel::RowCategory::MultiRoleItem | 1 | QRangeModel presentará los elementos con un meta-objeto como elementos multi-rol, también cuando se utiliza en un rango unidimensional. |
Especialice la plantilla RowOptions para su tipo, y añada una variable miembro pública static constexpr auto rowCategory con uno de los valores de este enum.
Véase también RowOptions.
Documentación de propiedades
[since 6.11] autoConnectPolicy : AutoConnectPolicy
si y cuando el modelo se auto-conecta a las notificaciones de cambio de propiedades.
Si QRangeModel opera sobre una estructura de datos que contiene el mismo tipo de subclase QObject que su tipo de fila o elemento, entonces puede conectar automáticamente las propiedades de los QObjects a la señal dataChanged(). Para QObject filas, esto se hace para cada columna, mapeando a la propiedad Qt::DisplayRole. Para los ítems, esto se hace para aquellas propiedades que coincidan con una de las role names.
Por defecto, el valor de esta propiedad es None, por lo que no se realizan estas conexiones. Cambiar el valor de esta propiedad siempre rompe todas las conexiones existentes.
Nota: Las conexiones no se rompen ni se crean si se intercambian QObjects en la estructura de datos sobre la que opera QRangeModel.
Esta propiedad se introdujo en Qt 6.11.
Funciones de acceso:
| QRangeModel::AutoConnectPolicy | autoConnectPolicy() const |
| void | setAutoConnectPolicy(QRangeModel::AutoConnectPolicy policy) |
Señal de notificador:
| void | autoConnectPolicyChanged(QRangeModel::AutoConnectPolicy policy) |
Véase también roleNames().
roleNames : QHash<int, QByteArray>
Esta propiedad contiene los nombres de las funciones del modelo.
Si todas las columnas del rango son del mismo tipo, y si ese tipo proporciona un metaobjeto (es decir, es un gadget, o una subclase de QObject ), entonces esta propiedad contiene los nombres de las propiedades de ese tipo, asignadas a valores de Qt::ItemDataRole a partir de Qt::UserRole. Además, un rol "modelData" proporciona acceso a la instancia del gadget o QObject.
Anule este comportamiento predeterminado estableciendo esta propiedad explícitamente a una asignación no vacía. Establecer esta propiedad a una asignación vacía, o utilizar resetRoleNames(), restaura el comportamiento por defecto.
Funciones de acceso:
| virtual QHash<int, QByteArray> | roleNames() const override |
| void | setRoleNames(const QHash<int, QByteArray> &names) |
| void | resetRoleNames() |
Señal de notificador:
| void | roleNamesChanged() |
Véase también QAbstractItemModel::roleNames().
Documentación de las funciones miembro
[explicit] template <typename Range, int = true> QRangeModel::QRangeModel(Range &&range, QObject *parent = nullptr)
[explicit] template <typename Range, int = true> QRangeModel::QRangeModel(Range &&range, QObject *parent = nullptr)
[explicit] template <
typename Range,
typename Protocol,
int = true
>
QRangeModel::QRangeModel(Range &&range, Protocol &&protocol, QObject *parent = nullptr)
Construye una instancia de QRangeModel que opera con los datos de range. range tiene que ser un rango secuencial para el que el compilador encuentre sobrecargas de begin y end a través de la búsqueda dependiente de argumentos, o para el que std::begin y std::end estén implementados. Si se proporciona protocol, el modelo representará el rango como un árbol utilizando la implementación del protocolo. La instancia del modelo se convierte en hija de parent.
range puede ser un puntero o una envoltura de referencia, en cuyo caso las API mutantes del modelo (como setData() o insertRow()) modificarán los datos de la instancia de rango referenciada. Si range es un valor (o se mueve dentro del modelo), entonces se conectará a las señales emitidas por el modelo para responder a los cambios en los datos.
QRangeModel no accederá a range mientras se construye. Esto hace que sea legal pasar a este constructor un puntero o referencia a un objeto de rango que aún no está completamente construido, por ejemplo cuando subclassing QRangeModel.
Si el range fue movido al modelo, entonces el rango y todos los datos en él serán destruidos al destruirse el modelo.
Nota: Aunque el modelo no se apropia del objeto rango de otro modo, no debes modificar el range directamente una vez que el modelo ha sido construido y y pasado a una vista. Tales modificaciones no emitirán las señales necesarias para mantener a los usuarios del modelo (otros modelos o vistas) sincronizados con el modelo, lo que provocará resultados incoherentes, comportamientos indefinidos y bloqueos. Utilice QRangeModelAdapter para interactuar de forma segura con el rango subyacente mientras mantiene el modelo actualizado.
Véase también QRangeModelAdapter.
[override virtual noexcept] QRangeModel::~QRangeModel()
Destruye el QRangeModel.
No se accede al rango desde el que se construyó el modelo, y sólo se destruye si el modelo se construyó desde un rango movido.
[override virtual] QModelIndex QRangeModel::buddy(const QModelIndex &index) const
Reimplementa: QAbstractItemModel::buddy(const QModelIndex &index) const.
[override virtual] bool QRangeModel::canDropMimeData(const QMimeData *data, Qt::DropAction action, int row, int column, const QModelIndex &parent) const
Reimplementa: QAbstractItemModel::canDropMimeData(const QMimeData *data, Qt::DropAction action, int row, int column, const QModelIndex &parent) const.
[override virtual] bool QRangeModel::canFetchMore(const QModelIndex &parent) const
Reimplementa: QAbstractItemModel::canFetchMore(const QModelIndex &parent) const.
[override virtual] bool QRangeModel::clearItemData(const QModelIndex &index)
Reimplementa: QAbstractItemModel::clearItemData(const QModelIndex &index).
Sustituye el valor almacenado en el rango en index por un valor construido por defecto.
Para los modelos que operan en un rango de sólo lectura, o en una columna de sólo lectura en un tipo de fila que implementa the C++ tuple protocol, esta implementación devuelve false inmediatamente.
[override virtual] int QRangeModel::columnCount(const QModelIndex &parent = {}) const
Reimplementa: QAbstractItemModel::columnCount(const QModelIndex &parent) const.
Devuelve el número de columnas del modelo. Esta función devuelve el mismo valor para todos los índices de parent.
Para los modelos que operan en un tipo de fila de tamaño estático, este valor devuelto es siempre el mismo durante toda la vida del modelo. Para los modelos que funcionan con un tipo de fila de tamaño dinámico, el modelo devuelve el número de elementos de la primera fila, o 0 si el modelo no tiene filas.
Véase también rowCount y insertColumns().
[override virtual] QVariant QRangeModel::data(const QModelIndex &index, int role = Qt::DisplayRole) const
Reimplementa: QAbstractItemModel::data(const QModelIndex &index, int rol) const.
Devuelve los datos almacenados bajo el role dado para el valor en el rango referido por el index.
Si el tipo de elemento para ese índice es un contenedor asociativo que mapea desde int, Qt::ItemDataRole, o QString a un QVariant, entonces los datos del rol se buscan en ese contenedor y se devuelven.
Si el elemento es un gadget o QObject, la implementación devuelve el valor de la propiedad del elemento que coincida con la entrada role de la asignación roleNames() .
En caso contrario, la implementación devuelve un QVariant construido a partir del elemento a través de QVariant::fromValue() para Qt::DisplayRole o Qt::EditRole. Para otros roles, la implementación devuelve un QVariantno válido (construido por defecto).
Véase también Qt::ItemDataRole, setData(), y headerData().
[override virtual] bool QRangeModel::dropMimeData(const QMimeData *data, Qt::DropAction action, int row, int column, const QModelIndex &parent)
Reimplementa: QAbstractItemModel::dropMimeData(const QMimeData *data, Qt::DropAction action, int row, int column, const QModelIndex &parent).
[override virtual protected] bool QRangeModel::event(QEvent *event)
Reimplementa: QObject::event(QEvent *e).
[override virtual protected] bool QRangeModel::eventFilter(QObject *object, QEvent *event)
Reimplementa: QObject::eventFilter(QObject *watched, QEvent *event).
[override virtual] void QRangeModel::fetchMore(const QModelIndex &parent)
Reimplementa: QAbstractItemModel::fetchMore(const QModelIndex &parent).
[override virtual] Qt::ItemFlags QRangeModel::flags(const QModelIndex &index) const
Reimplementa: QAbstractItemModel::flags(const QModelIndex &index) const.
Devuelve las banderas de elemento para el index dado.
La implementación devuelve una combinación de indicadores que habilitan el elemento (ItemIsEnabled) y permiten seleccionarlo (ItemIsSelectable). Para los modelos que operan en un rango con datos mutables, también establece la bandera que permite que el elemento sea editable (ItemIsEditable).
Véase también Qt::ItemFlags.
[override virtual] bool QRangeModel::hasChildren(const QModelIndex &parent = QModelIndex()) const
Reimplementa: QAbstractItemModel::hasChildren(const QModelIndex &parent) const.
[override virtual] QVariant QRangeModel::headerData(int section, Qt::Orientation orientation, int role = Qt::DisplayRole) const
Reimplementa: QAbstractItemModel::headerData(int section, Qt::Orientation orientation, int role) const.
Devuelve los datos de role y section dados en la cabecera con el orientation especificado.
Para cabeceras horizontales, el número de sección corresponde al número de columna. Del mismo modo, para las cabeceras verticales, el número de sección corresponde al número de fila.
Para la cabecera horizontal y el Qt::DisplayRole role , los modelos que operan sobre un rango que utiliza un array como tipo de fila devuelven section. Si el tipo de fila es una tupla, la implementación devuelve el nombre del tipo en section. Para las filas que son de tipo gadget o QObject, esta función devuelve el nombre de la propiedad en el índice de section.
Para la cabecera vertical, esta función siempre devuelve el resultado de la implementación por defecto en QAbstractItemModel.
Véase también Qt::ItemDataRole, setHeaderData(), y QHeaderView.
[override virtual] QModelIndex QRangeModel::index(int row, int column, const QModelIndex &parent = {}) const
Reimplementa: QAbstractItemModel::index(int fila, int columna, const QModelIndex &parent) const.
Devuelve el índice del elemento del modelo en row y column en parent.
Pasar un padre válido produce un índice inválido para modelos que operan sobre rangos de listas y tablas.
Véase también parent().
[override virtual] bool QRangeModel::insertColumns(int column, int count, const QModelIndex &parent = {})
Reimplementa: QAbstractItemModel::insertColumns(int columna, int cuenta, const QModelIndex &parent).
Inserta count columnas vacías antes del elemento en column en todas las filas del rango en parent. Devuelve true si tiene éxito; en caso contrario devuelve false.
Nota: Un tipo de fila de tamaño dinámico necesita proporcionar una función miembro insert(const_iterator, size_t, value_type).
Para los modelos que operan en un rango de sólo lectura, o en un rango con un tipo de fila de tamaño estático (como una tupla, matriz o estructura), esta implementación no hace nada y devuelve false inmediatamente. Este es siempre el caso de los modelos de árbol.
[override virtual] bool QRangeModel::insertRows(int row, int count, const QModelIndex &parent = {})
Reimplementa: QAbstractItemModel::insertRows(int fila, int cuenta, const QModelIndex &parent).
Inserta count filas vacías antes de la dada row en el rango en parent. Devuelve true si tiene éxito; en caso contrario devuelve false.
Nota: El rango debe tener un tamaño dinámico y proporcionar una función miembro insert(const_iterator, size_t, value_type).
Para modelos que operan en un rango de sólo lectura o de tamaño estático (como un array), esta implementación no hace nada y devuelve false inmediatamente.
Nota: Para rangos con un tipo de columna de tamaño dinámico, la columna debe proporcionar una función miembro resize(size_t).
[override virtual] QMap<int, QVariant> QRangeModel::itemData(const QModelIndex &index) const
Reimplementa: QAbstractItemModel::itemData(const QModelIndex &index) const.
Devuelve un mapa con valores para todos los roles predefinidos en el modelo para el ítem en el index dado.
Si el tipo de elemento para ese index es un contenedor asociativo que mapea desde int, Qt::ItemDataRole, o QString a un QVariant, entonces se devuelven los datos de ese contenedor.
Si el tipo de elemento es un gadget o una subclase de QObject, se devolverán los valores de las propiedades que coincidan con role name.
Si el elemento no es un contenedor asociativo, gadget o subclase de QObject, entonces se llama a la implementación de la clase base.
Véase también setItemData(), Qt::ItemDataRole, y data().
[override virtual] QModelIndexList QRangeModel::match(const QModelIndex &start, int role, const QVariant &value, int hits, Qt::MatchFlags flags) const
Reimplementa: QAbstractItemModel::match(const QModelIndex &start, int role, const QVariant &value, int hits, Qt::MatchFlags flags) const.
[override virtual] QMimeData *QRangeModel::mimeData(const QModelIndexList &indexes) const
Reimplementa: QAbstractItemModel::mimeData(const QModelIndexList &indexes) const.
[override virtual] QStringList QRangeModel::mimeTypes() const
Reimplementa: QAbstractItemModel::mimeTypes() const.
[override virtual] bool QRangeModel::moveColumns(const QModelIndex &sourceParent, int sourceColumn, int count, const QModelIndex &destinationParent, int destinationColumn)
Reimplementa: QAbstractItemModel::moveColumns(const QModelIndex &sourceParent, int sourceColumn, int count, const QModelIndex &destinationParent, int destinationChild).
Mueve las columnas de count que comienzan con la dada sourceColumn bajo el padre sourceParent a la columna destinationColumn bajo el padre destinationParent.
Devuelve true si las columnas se han movido correctamente; en caso contrario devuelve false.
[override virtual] bool QRangeModel::moveRows(const QModelIndex &sourceParent, int sourceRow, int count, const QModelIndex &destinationParent, int destinationRow)
Reimplementa: QAbstractItemModel::moveRows(const QModelIndex &sourceParent, int sourceRow, int count, const QModelIndex &destinationParent, int destinationChild).
Mueve count filas comenzando con la dada sourceRow bajo el padre sourceParent a la fila destinationRow bajo el padre destinationParent.
Devuelve true si las filas se han movido correctamente; en caso contrario devuelve false.
[override virtual] void QRangeModel::multiData(const QModelIndex &index, QModelRoleDataSpan roleDataSpan) const
Reimplementa: QAbstractItemModel::multiData(const QModelIndex &index, QModelRoleDataSpan roleDataSpan) const.
[override virtual] QModelIndex QRangeModel::parent(const QModelIndex &child) const
Reimplementa: QAbstractItemModel::parent(const QModelIndex &index) const.
Devuelve el padre del elemento en el índice child.
Esta función siempre produce un índice inválido para modelos que operan sobre rangos de listas y tablas. Para los modelos que operan sobre un árbol, esta función devuelve el índice del elemento de fila devuelto por la implementación parent() del protocolo de recorrido del árbol.
Véase también index() y hasChildren().
[override virtual] bool QRangeModel::removeColumns(int column, int count, const QModelIndex &parent = {})
Reimplementa: QAbstractItemModel::removeColumns(int columna, int cuenta, const QModelIndex &parent).
Elimina count columnas del elemento en column en todas las filas del rango en parent. Devuelve true si tiene éxito, en caso contrario devuelve false.
Nota: Un tipo de fila de tamaño dinámico necesita proporcionar una función miembro erase(const_iterator, size_t).
Para los modelos que operan en un rango de sólo lectura, o en un rango con un tipo de fila de tamaño estático (como una tupla, matriz o estructura), esta implementación no hace nada y devuelve false inmediatamente. Este es siempre el caso de los modelos de árbol.
[override virtual] bool QRangeModel::removeRows(int row, int count, const QModelIndex &parent = {})
Reimplementa: QAbstractItemModel::removeRows(int fila, int cuenta, const QModelIndex &parent).
Elimina count filas del rango en parent, empezando por el row dado. Devuelve true si tiene éxito, en caso contrario devuelve false.
Nota: El rango debe tener un tamaño dinámico y proporcionar una función miembro erase(const_iterator, size_t).
Para los modelos que operan en un rango de sólo lectura o de tamaño estático (como un array), esta implementación no hace nada y devuelve false inmediatamente.
[override virtual protected slot] void QRangeModel::resetInternalData()
Reimplementa: QAbstractItemModel::resetInternalData().
[override virtual] QHash<int, QByteArray> QRangeModel::roleNames() const
Reimplementa: QAbstractItemModel::roleNames() const.
Nota: Es posible sobreescribir esta función en una subclase de QRangeModel, pero podría romper el comportamiento de la propiedad.
Nota: Función Getter para la propiedad roleNames.
Véase también setRoleNames().
[override virtual] int QRangeModel::rowCount(const QModelIndex &parent = {}) const
Reimplementa: QAbstractItemModel::rowCount(const QModelIndex &parent) const.
Devuelve el número de filas bajo el parent dado. Este es el número de elementos en el rango raíz para un índice parent inválido.
Si el índice parent es válido, esta función siempre devuelve 0 para los modelos que operan con rangos de listas y tablas. Para árboles, devuelve el tamaño del rango devuelto por la implementación de childRows() del protocolo de recorrido del árbol.
Véase también columnCount(), insertRows() y hasChildren().
[override virtual] bool QRangeModel::setData(const QModelIndex &index, const QVariant &data, int role = Qt::EditRole)
Reimplementa: QAbstractItemModel::setData(const QModelIndex &index, const QVariant &value, int role).
Establece los datos de role para el elemento en index a data.
Si el tipo de elemento para ese index es un contenedor asociativo que mapea desde int, Qt::ItemDataRole, o QString a un QVariant, entonces data se almacena en ese contenedor para la clave especificada por role.
Si el elemento es un gadget o QObject, entonces data se escribe en la propiedad del elemento que coincide con la entrada role en la asignación roleNames(). La función devuelve true si se ha encontrado una propiedad y si data almacenaba un valor que podía convertirse al tipo requerido; en caso contrario, devuelve false.
De lo contrario, esta implementación asigna el valor en data al elemento en el index en el rango para Qt::DisplayRole y Qt::EditRole, y devuelve true. Para otros roles, la implementación devuelve false.
Para los modelos que operan en un rango de sólo lectura, o en una columna de sólo lectura en un tipo de fila que implementa the C++ tuple protocol, esta implementación devuelve false inmediatamente.
Véase también data().
[override virtual] bool QRangeModel::setHeaderData(int section, Qt::Orientation orientation, const QVariant &data, int role = Qt::EditRole)
Reimplementa: QAbstractItemModel::setHeaderData(int section, Qt::Orientation orientation, const QVariant &value, int role).
Véase también headerData().
[override virtual] bool QRangeModel::setItemData(const QModelIndex &index, const QMap<int, QVariant> &data)
Reimplementa: QAbstractItemModel::setItemData(const QModelIndex &index, const QMap<int, QVariant> &roles).
Si el tipo de elemento para ese index es un contenedor asociativo que mapea desde int o Qt::ItemDataRole a un QVariant, entonces las entradas en data se almacenan en ese contenedor. Si el contenedor asociativo asigna de QString a QVariant, sólo se almacenarán los valores de data para los que exista una asignación en la tabla role names.
Si el tipo de elemento es un gadget o una subclase de QObject, entonces aquellas propiedades que coincidan con un role name se establecen en el valor correspondiente en data.
Los roles para los que no hay entrada en data no se modifican.
Para los tipos de elementos que pueden copiarse, esta implementación es transaccional, y devuelve true si todas las entradas de data pudieron almacenarse. Si alguna entrada no se ha podido actualizar, el contenedor original no se modifica en absoluto y la función devuelve false.
Si el elemento no es un contenedor asociativo, un gadget o una subclase de QObject, entonces se llama a la implementación de la clase base, que llama a setData() para cada entrada de data.
Véase también itemData(), setData(), y Qt::ItemDataRole.
[override virtual] QModelIndex QRangeModel::sibling(int row, int column, const QModelIndex &index) const
Reimplementa: QAbstractItemModel::sibling(int fila, int columna, const QModelIndex &index) const.
Devuelve el hermano en row y column para el elemento en index, o un QModelIndex inválido si no hay hermano en esa ubicación.
Esta implementación es significativamente más rápida que pasar por parent() de index.
Véase también index(), QModelIndex::row() y QModelIndex::column().
[override virtual] void QRangeModel::sort(int column, Qt::SortOrder order = Qt::AscendingOrder)
Reimplementa: QAbstractItemModel::sort(int columna, Qt::SortOrder orden).
[override virtual] QSize QRangeModel::span(const QModelIndex &index) const
Reimplementa: QAbstractItemModel::span(const QModelIndex &index) const.
[override virtual] Qt::DropActions QRangeModel::supportedDragActions() const
Reimplementa: QAbstractItemModel::supportedDragActions() const.
[override virtual] Qt::DropActions QRangeModel::supportedDropActions() const
Reimplementa: QAbstractItemModel::supportedDropActions() const.
© 2026 The Qt Company Ltd. Documentation contributions included herein are the copyrights of their respective owners. The documentation provided herein is licensed under the terms of the GNU Free Documentation License version 1.3 as published by the Free Software Foundation. Qt and respective logos are trademarks of The Qt Company Ltd. in Finland and/or other countries worldwide. All other trademarks are property of their respective owners.