QRangeModel Class
QRangeModel implémente QAbstractItemModel pour toute plage C++. Plus d'informations...
| En-tête : | #include <QRangeModel> |
| CMake : | find_package(Qt6 REQUIRED COMPONENTS Core)target_link_libraries(mytarget PRIVATE Qt6::Core) |
| qmake : | QT += core |
| Depuis : | Qt 6.10 |
| Hérite : | QAbstractItemModel |
Note : Toutes les fonctions de cette classe sont réentrantes.
Types publics
(since 6.11) struct | ItemAccess |
(since 6.10) struct | RowOptions |
(since 6.11) enum class | AutoConnectPolicy { None, Full, OnRead } |
| enum class | RowCategory { Default, MultiRoleItem } |
Propriétés
(since 6.11)autoConnectPolicy : AutoConnectPolicy- roleNames : QHash<int, QByteArray>
Fonctions publiques
| 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) |
Fonctions publiques réimplémentées
| 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 |
Signaux
| void | autoConnectPolicyChanged(QRangeModel::AutoConnectPolicy policy) |
| void | roleNamesChanged() |
Fonctions protégées réimplémentées
| virtual bool | event(QEvent *event) override |
| virtual bool | eventFilter(QObject *object, QEvent *event) override |
Emplacements protégés
| virtual void | resetInternalData() override |
Description détaillée
QRangeModel peut mettre les données de n'importe quel type C++ itérable séquentiellement à la disposition du cadre modèle/vue de Qt. Cela facilite l'affichage des structures de données existantes dans les vues Qt Widgets et Qt Quick et permet à l'utilisateur de l'application de manipuler les données à l'aide d'une interface graphique.
Pour utiliser QRangeModel, instanciez-le avec une plage C++ et définissez-le comme modèle d'une ou plusieurs vues :
std::array<int, 5> numbers = {1, 2, 3, 4, 5}; QRangeModel model(numbers); listView.setModel(&model);
Construction du modèle
La plage peut être n'importe quel type C++ pour lequel les méthodes standard std::begin et std::end sont implémentées et pour lequel le type d'itérateur retourné satisfait à std::forward_iterator. Certaines opérations du modèle seront plus performantes si std::size est disponible et si l'itérateur satisfait à std::random_access_iterator.
L'intervalle doit être fourni lors de la construction du modèle et peut être fourni sous forme de valeur, d'enveloppe de référence ou de pointeur. La façon dont le modèle a été construit détermine si les modifications apportées par l'intermédiaire de l'API du modèle modifieront les données d'origine. Utilisez QRangeModelAdapter pour construire implicitement un modèle tout en ayant un accès direct, sûr et pratique au modèle en tant que plage.
Lorsqu'il est construit par valeur, le modèle fait une copie de la plage et les API QAbstractItemModel qui modifient le modèle, telles que setData() ou insertRows(), n'ont aucun impact sur la plage d'origine.
QRangeModel model(numbers);Les modifications apportées aux données peuvent être contrôlées en se connectant aux signaux émis par le modèle, comme dataChanged().
Pour que les modifications du modèle aient un impact sur la plage originale, il faut fournir la plage soit par un pointeur :
QRangeModel model(&numbers);
soit par l'intermédiaire d'un wrapper de référence :
QRangeModel model(std::ref(numbers));
Dans ce cas, les API QAbstractItemModel qui modifient le modèle modifient également la plage. Les méthodes qui modifient la structure de la plage, telles que insertRows() ou removeColumns(), utilisent les API de conteneur standard du C++ resize(), insert(), erase(), en plus du déréférencement d'un itérateur mutant pour définir ou effacer les données.
Remarque : une fois que le modèle a été construit et transmis à une vue, la plage sur laquelle le modèle opère ne doit plus être modifiée directement. Les vues sur le modèle ne seraient pas informées des changements, et les changements structurels sont susceptibles de corrompre les instances de QPersistentModelIndex que le modèle maintient. Utilisez QRangeModelAdapter pour interagir en toute sécurité avec la plage sous-jacente tout en maintenant le modèle à jour.
L'appelant doit s'assurer que la durée de vie de la plage dépasse celle du modèle.
Utilisez des pointeurs intelligents pour vous assurer que la plage n'est supprimée que lorsque tous les clients en ont terminé avec elle.
auto shared_numbers = std::make_shared<std::vector<int>>(numbers); QRangeModel model(shared_numbers);
QRangeModel prend en charge les pointeurs partagés et uniques.
Lecture seule ou mutable
Pour les plages qui sont des objets constants, pour lesquels l'accès produit toujours des valeurs constantes, ou lorsque les API de conteneur requises ne sont pas disponibles, QRangeModel implémente des API d'accès en écriture pour ne rien faire et renvoyer false. Dans l'exemple utilisant std::array, le modèle ne peut pas ajouter ou supprimer des lignes, car le nombre d'entrées dans un tableau C++ est fixe. Mais les valeurs peuvent être modifiées à l'aide de setData(), et l'utilisateur peut déclencher l'édition des valeurs dans la vue en liste. En rendant le tableau constant, les valeurs deviennent également en lecture seule.
const std::array<int, 5> numbers = {1, 2, 3, 4, 5};
Les valeurs sont également en lecture seule si le type d'élément est const, comme dans l'exemple suivant
std::array<const int, 5> numbers = {1, 2, 3, 4, 5};
Dans les exemples ci-dessus utilisant std::vector, le modèle peut ajouter ou supprimer des lignes et les données peuvent être modifiées. Le fait de passer la plage en tant que référence constante rendra le modèle en lecture seule.
QRangeModel model(std::cref(numbers));
Remarque : si les valeurs de la plage sont constantes, il n'est pas non plus possible de supprimer ou d'insérer des colonnes et des lignes via l'API QAbstractItemModel. Pour un contrôle plus granulaire, implémentez the C++ tuple protocol.
Lignes et colonnes
Les éléments de la plage sont interprétés comme des lignes du modèle. Selon le type de ces éléments de ligne, QRangeModel expose la plage sous la forme d'une liste, d'un tableau ou d'un arbre.
Si les éléments de la ligne sont des valeurs simples, la plage est représentée sous la forme d'une liste.
QList<int> numbers = {1, 2, 3, 4, 5}; QRangeModel model(numbers); // columnCount() == 1 QListView listView; listView.setModel(&model);
Si le type des éléments de ligne est une plage itérable, telle qu'un vecteur, une liste ou un tableau, la plage est représentée sous la forme d'un tableau.
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 le type de ligne fournit les API de conteneur C++ standard resize(), insert(), erase(), les colonnes peuvent être ajoutées et supprimées via insertColumns() et removeColumns(). Toutes les lignes doivent avoir le même nombre de colonnes.
Structures et gadgets en tant que lignes
Si le type de ligne met en œuvre the C++ tuple protocol, la plage est représentée sous la forme d'un tableau avec un nombre fixe de colonnes.
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);
Une alternative plus simple et plus flexible à l'implémentation du protocole tuple pour un type C++ consiste à utiliser le système de méta-objets de Qt pour déclarer un type avec des propriétés. Il peut s'agir d'un type de valeur déclaré comme gadget ou d'une sous-classe 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; };
L'utilisation des sous-classes QObject permet aux propriétés d'être liées ou d'avoir des signaux de notification de changement. Cependant, l'utilisation d'instances QObject pour les éléments entraîne une surcharge de mémoire importante.
L'utilisation de gadgets ou d'objets Qt est plus pratique et peut être plus flexible que l'implémentation du protocole tuple. Ces types sont également directement accessibles à partir de QML. Cependant, l'accès par le système de propriétés s'accompagne d'une surcharge d'exécution. Pour les modèles critiques en termes de performances, il convient d'envisager la mise en œuvre du protocole tuple pour la génération du code d'accès au moment de la compilation.
Éléments multirôles
Le type des éléments sur lesquels opèrent les implémentations de data(), setData(), clearItemData(), etc. peut être le même dans l'ensemble du modèle - comme dans l'exemple gridOfNumbers ci-dessus. Mais la plage peut également avoir différents types d'éléments pour différentes colonnes, comme dans le cas de numberNames.
Par défaut, la valeur est utilisée pour les rôles Qt::DisplayRole et Qt::EditRole. La plupart des vues s'attendent à ce que la valeur soit convertible to and from a QString (mais un délégué personnalisé peut offrir plus de flexibilité).
Conteneurs associatifs avec plusieurs rôles
Si l'élément est un conteneur associatif qui utilise int, Qt::ItemDataRole ou QString comme type de clé et QVariant comme type mappé, QRangeModel interprète ce conteneur comme le stockage des données pour des rôles multiples. Les fonctions data() et setData() renvoient et modifient la valeur mappée dans le conteneur, et setItemData() modifie toutes les valeurs fournies, itemData() renvoie toutes les valeurs stockées, et clearItemData() efface tout le conteneur.
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);
Le type de données le plus efficace à utiliser comme clé est Qt::ItemDataRole ou int. Lorsque vous utilisez int, itemData() renvoie le conteneur tel quel et ne doit pas créer de copie des données.
Gadgets et objets en tant qu'éléments multirôles
Les gadgets et les types QObject peuvent également être représentés comme des éléments multirôles. Les propriétés de ces éléments seront utilisées pour le rôle auquel correspond le name of a role. Si tous les éléments contiennent le même type de gadget ou QObject, l'implémentation de roleNames() dans QRangeModel renverra la liste des propriétés de ce type.
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; };
Lorsqu'elle est utilisée dans un tableau, il s'agit de la représentation par défaut des gadgets :
QList<QList<ColorEntry>> colorTable; // ... QRangeModel colorModel(colorTable); QTableView table; table.setModel(&colorModel);
Lorsqu'ils sont utilisés dans une liste, ces types sont toutefois représentés par défaut comme des lignes à plusieurs colonnes, chaque propriété étant représentée par une colonne distincte. Pour forcer un gadget à être représenté comme un élément multirôle dans une liste, déclarez le gadget comme un type multirôle en spécialisant QRoleModel::RowOptions, avec une variable membre static constexpr auto rowCategory fixée à 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; };
Vous pouvez également envelopper ces types dans un tuple à un seul élément, transformant ainsi la liste en un tableau à une seule colonne :
const QStringList colorNames = QColor::colorNames(); QList<std::tuple<ColorEntry>> colors; // ... QRangeModel colorModel(colors); QListView list; list.setModel(&colorModel);
Dans ce cas, notez que l'accès direct aux éléments des données de la liste doit utiliser std::get:
ColorEntry firstEntry = std::get<0>(colors.at(0));
ou, à défaut, une liaison structurée :
auto [firstEntry] = colors.at(0);
Lignes en tant que valeurs ou pointeurs
Dans les exemples présentés jusqu'à présent, nous avons toujours utilisé QRangeModel avec des plages contenant des valeurs. QRangeModel peut également opérer sur des plages contenant des pointeurs, y compris des pointeurs intelligents. Cela permet à QRangeModel d'opérer sur des plages de types polymorphes, tels que les sous-classes 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);
Comme pour les valeurs, le type de la ligne détermine si la plage est représentée sous forme de liste, de tableau ou d'arbre. Les lignes qui sont des QObjects présenteront chaque propriété sous la forme d'une colonne, à moins que le modèle QRangeModel::RowOptions ne soit spécialisé pour déclarer le type comme un élément multirôle.
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));
Remarque : si la plage contient des pointeurs bruts, vous devez construire QRangeModel à partir d'un pointeur ou d'une enveloppe de référence de la plage. Sinon, la propriété des données devient ambiguë, et une copie de la plage fonctionnerait toujours sur les mêmes données de ligne réelles, ce qui entraînerait des effets secondaires inattendus.
Sous-classement de QRangeModel
La sous-classification de QRangeModel permet d'ajouter des API pratiques qui prennent en compte le type de données et la structure de la plage.
class NumbersModel : public QRangeModel { std::vector<int> m_numbers; public: NumbersModel(const std::vector<int> &numbers) : QRangeModel(std::ref(m_numbers)) , m_numbers(numbers) { }
Pour ce faire, ajoutez la plage en tant que membre privé et appelez le constructeur de QRangeModel avec une enveloppe de référence ou un pointeur vers ce membre. Cela permet d'encapsuler correctement les données et d'éviter l'accès direct.
void setNumber(int idx, int number) { setData(index(idx, 0), QVariant::fromValue(number)); } int number(int idx) const { return m_numbers.at(idx); } };
Ajoutez des fonctions membres pour fournir un accès sécurisé aux données, en utilisant l'API QAbstractItemModel pour effectuer toute opération qui modifie la plage. L'accès en lecture seule permet d'opérer directement sur la structure de données.
Arbres de données
QRangeModel peut représenter une structure de données sous la forme d'un modèle arborescent. Une telle structure de données arborescente doit être homomorphe : à tous les niveaux de l'arbre, la liste des lignes enfants doit utiliser exactement la même représentation que l'arbre lui-même. En outre, le type de ligne doit être de taille statique : soit un type gadget ou QObject, soit un type qui implémente the C++ tuple protocol.
Pour représenter ces données sous la forme d'un arbre, QRangeModel doit pouvoir parcourir la structure de données : pour toute ligne donnée, le modèle doit pouvoir récupérer la ligne parentale et la portée facultative des enfants. Ces fonctions de traversée peuvent être fournies implicitement par le type de ligne ou par un type de protocole explicite.
Protocole de traversée d'arbre implicite
class TreeRow; using Tree = std::vector<TreeRow>;
L'arbre lui-même est un vecteur de valeurs TreeRow. Voir Tree Rows as pointers or values pour savoir s'il faut utiliser des valeurs ou des pointeurs d'éléments pour les lignes.
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 classe de lignes peut être de n'importe quel type de taille fixe décrit ci-dessus : un type qui met en œuvre le protocole tuple, un gadget ou un QObject. Dans cet exemple, nous utilisons un gadget.
Chaque élément de ligne doit maintenir un pointeur sur la ligne parent, ainsi qu'une plage facultative de lignes enfant. Cet intervalle doit être identique à la structure d'intervalle utilisée pour l'arbre lui-même.
Rendre constructible le type de ligne par défaut est facultatif et permet au modèle de construire de nouveaux éléments de données de ligne, par exemple dans les implémentations insertRow() ou moveRows().
// tree traversal protocol implementation const TreeRow *parentRow() const { return m_parent; } const std::optional<Tree> &childRows() const { return m_children; }
Le protocole de traversée de l'arbre peut alors être mis en œuvre en tant que fonctions membres du type de données de ligne. Une fonction const parentRow() doit renvoyer un pointeur sur un élément de ligne ; et la fonction childRows() doit renvoyer une référence à une const std::optional qui peut contenir la plage d'enfants facultative.
Ces deux fonctions suffisent au modèle pour naviguer dans l'arbre en tant que structure de données en lecture seule. Pour permettre à l'utilisateur de modifier les données dans une vue et au modèle de mettre en œuvre des API de modèle mutant telles que insertRows(), removeRows() et moveRows(), nous devons mettre en œuvre des fonctions supplémentaires pour l'accès en écriture :
void setParentRow(TreeRow *parent) { m_parent = parent; } std::optional<Tree> &childRows() { return m_children; }
Le modèle appelle la fonction setParentRow() et la surcharge mutable childRows() pour déplacer ou insérer des lignes dans une branche d'arbre existante, et pour mettre à jour le pointeur parent si l'ancienne valeur est devenue invalide. La surcharge non-const de childRows() fournit en outre un accès en écriture aux données des lignes.
Remarque : le modèle définit le parent d'une ligne, supprime cette ligne de l'ancien parent et l'ajoute à la liste des enfants du nouveau parent en tant qu'étapes distinctes. Cela permet de réduire la taille de l'interface du protocole.
...
// 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;
}
};Le reste de l'implémentation de la classe n'est pas pertinent pour le modèle, mais une aide addChild() nous fournit un moyen pratique de construire l'état initial de l'arbre.
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 modèle QRangeModel instancié avec une instance d'une telle plage représentera les données sous la forme d'un arbre.
// instantiate the model with a pointer to the tree, not a copy! QRangeModel model(&tree); QTreeView view; view.setModel(&model);
Protocole de traversée d'arbre dans une classe séparée
Le protocole de parcours d'arbre peut également être mis en œuvre dans une classe distincte.
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; } };
Passez une instance de cette implémentation du protocole au constructeur de QRangeModel :
QRangeModel model(&tree, TreeTraversal{});
Les rangées de l'arbre en tant que pointeurs ou valeurs
Le type de ligne de la plage de données peut être soit une valeur, soit un pointeur. Dans le code ci-dessus, nous avons utilisé les lignes de l'arbre comme des valeurs dans un vecteur, ce qui nous évite d'avoir à gérer explicitement la mémoire. Cependant, un vecteur en tant que bloc de mémoire contiguë invalide tous les itérateurs et les références lorsqu'il doit réallouer le stockage, ou lorsqu'il insère ou supprime des éléments. Cela a un impact sur le pointeur de l'élément parent, qui est l'emplacement de la ligne parentale dans le vecteur. S'assurer que ce parent (et les instances QPersistentModelIndex se référant aux éléments qu'il contient) reste valide peut entraîner des surcoûts importants en termes de performances. L'implémentation du modèle QRangeModel doit supposer que toutes les références à la plage deviennent invalides lors de la modification de la plage.
Il est également possible d'utiliser une plage de pointeurs de ligne comme type d'arbre :
struct TreeRow; using Tree = std::vector<TreeRow *>;
Dans ce cas, nous devons allouer toutes les instances TreeRow explicitement à l'aide de l'opérateur new, et implémenter le destructeur pour delete tous les éléments du vecteur d'enfants.
struct TreeRow { Q_GADGETpublic: TreeRow(const QString &value = {}) : m_value(value) {} ~TreeRow() { if (m_children) qDeleteAll(*m_children); } // déplacer uniquementTreeRow(TreeRow &&) = default; TreeRow &operator=(TreeRow &&) = default; // aide pour remplir le modèle <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");
Avant de pouvoir construire un modèle qui représente ces données sous la forme d'un arbre, nous devons également mettre en œuvre le protocole de traversée des arbres.
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; } };
Une implémentation explicite du protocole pour les arbres mutables de pointeurs doit fournir deux fonctions membres supplémentaires, newRow() et 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(); }
Le modèle appellera ces fonctions lors de la création de nouvelles lignes dans insertRows() et lors de la suppression de lignes dans removeRows(). En outre, si le modèle est propriétaire des données, il supprimera également toutes les lignes de niveau supérieur lors de leur destruction. Notez que dans cet exemple, nous déplaçons l'arbre dans le modèle, de sorte que nous ne devons plus effectuer d'opérations sur lui. QRangeModel, lorsqu'il est construit en déplaçant des données arborescentes avec des pointeurs de ligne, prendra possession des données et supprimera les pointeurs de ligne dans son destructeur.
L'utilisation de pointeurs en tant que lignes s'accompagne d'une allocation de mémoire et d'une surcharge de gestion. Cependant, les références aux éléments de la ligne restent stables, même lorsqu'elles sont déplacées dans la plage ou lorsque la plage est réattribuée. Cela peut réduire considérablement le coût des modifications apportées à la structure du modèle lors de l'utilisation de insertRows(), removeRows() ou moveRows().
Chaque choix présente des compromis différents en termes de performances et de surcharge de mémoire. La meilleure option dépend du cas d'utilisation exact et de la structure de données utilisée.
Le protocole tuple C++
Comme nous l'avons vu dans l'exemple numberNames ci-dessus, le type de ligne peut être un tuple, et en fait n'importe quel type qui implémente le protocole tuple. Ce protocole est mis en œuvre en spécialisant std::tuple_size et std::tuple_element et en surchargeant la fonction non qualifiée get. Faites-le pour votre type de ligne personnalisé afin de rendre les données structurées existantes disponibles pour le cadre modèle/vue dans 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>())); }; }
Dans l'implémentation ci-dessus, les valeurs title et author du type Book sont renvoyées sous la forme const, de sorte que le modèle marque les éléments de ces deux colonnes comme étant en lecture seule. L'utilisateur ne pourra pas déclencher l'édition, et setData() ne fait rien et renvoie false. Pour summary et rating, l'implémentation renvoie la même catégorie de valeur que le livre, de sorte que lorsque get est appelé avec une référence mutable à Book, il renvoie une référence mutable de la variable correspondante. Le modèle rend ces colonnes modifiables, à la fois pour l'utilisateur et pour l'accès programmatique.
Remarque : l'implémentation de get ci-dessus nécessite C++23.
Considérations sur la compatibilité binaire
QRangeModel n'est pas une classe modèle. Le passage d'instances de QRangeModel (par pointeur ou référence, comme pour toutes les classes QObject ) à travers les API des bibliothèques, ou le stockage de QRangeModel par valeur dans une classe publique d'une bibliothèque, est sans danger.
Cependant, le constructeur de QRangeModel est un modèle et est en ligne, et l'implémentation interne spécialisée dans le type de la plage sur laquelle le modèle opère est instanciée dans le constructeur. Vous ne devez pas appeler le constructeur dans une implémentation en ligne d'une API de bibliothèque. Cela entraîne des violations de l'ODR et peut rompre la compatibilité binaire de cette bibliothèque si la version de Qt avec laquelle elle est construite est différente de la version de Qt avec laquelle une application utilisant cette bibliothèque est construite.
Voir aussi Programmation modèle/vue.
Documentation sur les types de membres
[since 6.11] enum class QRangeModel::AutoConnectPolicy
Cette énumération définit si et quand QRangeModel connecte automatiquement les signaux de changement des propriétés au signal dataChanged() du modèle. Seules les propriétés qui correspondent à l'une des role names sont connectées.
| Constante | Valeur | Description |
|---|---|---|
QRangeModel::AutoConnectPolicy::None | 0 | Aucune connexion n'est établie automatiquement. |
QRangeModel::AutoConnectPolicy::Full | 1 | Les signaux de toutes les propriétés pertinentes sont connectés automatiquement, pour tous les éléments QObject. Cela inclut les éléments QObject qui sont ajoutés aux lignes et colonnes nouvellement insérées. |
QRangeModel::AutoConnectPolicy::OnRead | 2 | Les signaux des propriétés pertinentes sont connectés la première fois que le modèle lit la propriété. |
La surcharge de mémoire liée à l'établissement de connexions automatiques peut être importante. Une connexion automatique complète ne nécessite pas de tenue de livres en plus de la connexion elle-même, mais chaque connexion prend de la mémoire, et connecter toutes les propriétés de tous les objets peut être très coûteux, en particulier si seules quelques propriétés d'un sous-ensemble d'objets sont modifiées.
La politique de connexion OnRead n'établit pas de connexion avec des objets ou des propriétés qui ne sont jamais lus (par exemple, qui ne sont jamais rendus dans une vue), mais le fait de se souvenir des connexions qui ont été établies nécessite une certaine surcharge de comptabilité et une croissance imprévisible de la mémoire au fil du temps. Par exemple, le défilement d'une longue liste d'éléments peut facilement entraîner l'établissement de milliers de nouvelles connexions.
Cette liste a été introduite dans Qt 6.11.
Voir aussi autoConnectPolicy et roleNames().
enum class QRangeModel::RowCategory
Cette énumération décrit comment QRangeModel doit présenter les éléments de la plage avec laquelle il a été construit.
| Constante | Valeur | Description |
|---|---|---|
QRangeModel::RowCategory::Default | 0 | QRangeModel décide de la manière de présenter les lignes. |
QRangeModel::RowCategory::MultiRoleItem | 1 | QRangeModel présentera les éléments avec un métaobjet comme des éléments multirôles, même lorsqu'ils sont utilisés dans une plage unidimensionnelle. |
Spécialisez le modèle RowOptions pour votre type et ajoutez une variable membre publique static constexpr auto rowCategory avec l'une des valeurs de cette énumération.
Voir également RowOptions.
Documentation sur les propriétés
[since 6.11] autoConnectPolicy : AutoConnectPolicy
si et quand le modèle se connecte automatiquement aux notifications de changement de propriété.
Si QRangeModel opère sur une structure de données qui contient le même type de sous-classe QObject que son type de ligne ou d'élément, il peut alors connecter automatiquement les propriétés des QObjects au signal dataChanged(). Pour les lignes QObject, cela se fait pour chaque colonne, en associant la propriété Qt::DisplayRole. Pour les éléments, cela est fait pour les propriétés qui correspondent à l'une des propriétés role names.
Par défaut, la valeur de cette propriété est None, de sorte qu'aucune connexion de ce type n'est établie. La modification de la valeur de cette propriété rompt toujours toutes les connexions existantes.
Remarque : les connexions ne sont pas rompues ou créées si les QObjects de la structure de données sur laquelle QRangeModel opère sont échangés.
Cette propriété a été introduite dans Qt 6.11.
Fonctions d'accès :
| QRangeModel::AutoConnectPolicy | autoConnectPolicy() const |
| void | setAutoConnectPolicy(QRangeModel::AutoConnectPolicy policy) |
Notifier signal :
| void | autoConnectPolicyChanged(QRangeModel::AutoConnectPolicy policy) |
Voir aussi roleNames().
roleNames : QHash<int, QByteArray>
Cette propriété contient les noms des rôles du modèle.
Si toutes les colonnes de la plage sont du même type et si ce type fournit un métaobjet (c'est-à-dire un gadget ou une sous-classe de QObject ), cette propriété contient les noms des propriétés de ce type, associées aux valeurs de Qt::ItemDataRole à partir de Qt::UserRole. En outre, le rôle "modelData" permet d'accéder à l'instance de gadget ou de QObject.
Remplacez ce comportement par défaut en définissant explicitement cette propriété avec un mappage non vide. La définition de cette propriété à un mappage vide ou l'utilisation de la fonction resetRoleNames() rétablit le comportement par défaut.
Fonctions d'accès :
| virtual QHash<int, QByteArray> | roleNames() const override |
| void | setRoleNames(const QHash<int, QByteArray> &names) |
| void | resetRoleNames() |
Notifier signal :
| void | roleNamesChanged() |
Voir aussi QAbstractItemModel::roleNames().
Documentation des fonctions membres
[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)
Construit une instance de QRangeModel qui opère sur les données de range. range doit être une plage séquentielle pour laquelle le compilateur trouve des surcharges begin et end par le biais d'une recherche dépendante de l'argument, ou pour laquelle std::begin et std::end sont implémentées. Si protocol est fourni, le modèle représentera la plage sous forme d'arbre en utilisant l'implémentation du protocole. L'instance du modèle devient un enfant de parent.
L'adresse range peut être un pointeur ou une enveloppe de référence, auquel cas la mutation des API du modèle (telles que setData() ou insertRow()) modifiera les données de l'instance de plage référencée. Si range est une valeur (ou déplacée dans le modèle), il faut se connecter aux signaux émis par le modèle pour répondre aux modifications des données.
QRangeModel n'accèdera pas à range pendant la construction. Il est donc légal de passer un pointeur ou une référence à un objet range qui n'est pas encore entièrement construit à ce constructeur, par exemple lorsque subclassing QRangeModel.
Si range a été déplacé dans le modèle, la plage et toutes les données qu'elle contient seront détruites lors de la destruction du modèle.
Note : Bien que le modèle ne prenne pas possession de l'objet range par ailleurs, vous ne devez pas modifier directement le range une fois que le modèle a été construit et transmis à une vue. De telles modifications n'émettront pas les signaux nécessaires pour maintenir les utilisateurs du modèle (autres modèles ou vues) synchronisés avec le modèle, ce qui entraînera des résultats incohérents, un comportement indéfini et des plantages. Utilisez QRangeModelAdapter pour interagir en toute sécurité avec la gamme sous-jacente tout en maintenant le modèle à jour.
Voir aussi QRangeModelAdapter.
[override virtual noexcept] QRangeModel::~QRangeModel()
Détruit le modèle QRangeModel.
La plage à partir de laquelle le modèle a été construit n'est pas accessible et n'est détruite que si le modèle a été construit à partir d'une plage déplacée.
[override virtual] QModelIndex QRangeModel::buddy(const QModelIndex &index) const
Réimplémente : 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
Réimplémente : 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
Réimplémente : QAbstractItemModel::canFetchMore(const QModelIndex &parent) const.
[override virtual] bool QRangeModel::clearItemData(const QModelIndex &index)
Réimplémente : QAbstractItemModel::clearItemData(const QModelIndex &index).
Remplace la valeur stockée dans l'intervalle à index par une valeur construite par défaut.
Pour les modèles fonctionnant sur une plage en lecture seule ou sur une colonne en lecture seule dans un type de ligne qui implémente the C++ tuple protocol, cette implémentation renvoie immédiatement false.
[override virtual] int QRangeModel::columnCount(const QModelIndex &parent = {}) const
Réimplémente : QAbstractItemModel::columnCount(const QModelIndex &parent) const.
Renvoie le nombre de colonnes du modèle. Cette fonction renvoie la même valeur pour tous les index parent.
Pour les modèles fonctionnant sur un type de ligne de taille statique, cette valeur retournée est toujours la même pendant toute la durée de vie du modèle. Pour les modèles fonctionnant sur des lignes de taille dynamique, le modèle renvoie le nombre d'éléments de la première ligne, ou 0 si le modèle n'a pas de lignes.
Voir aussi rowCount et insertColumns().
[override virtual] QVariant QRangeModel::data(const QModelIndex &index, int role = Qt::DisplayRole) const
Réimplémente : QAbstractItemModel::data(const QModelIndex &index, int role) const.
Renvoie les données stockées sous l'adresse role donnée pour la valeur de la plage visée par l'adresse index.
Si le type d'élément pour cet index est un conteneur associatif qui relie int, Qt::ItemDataRole, ou QString à QVariant, les données relatives au rôle sont recherchées dans ce conteneur et renvoyées.
Si l'élément est un gadget ou QObject, l'implémentation renvoie la valeur de la propriété de l'élément correspondant à l'entrée role dans le mappage roleNames().
Sinon, l'implémentation renvoie un QVariant construit à partir de l'élément via QVariant::fromValue() pour Qt::DisplayRole ou Qt::EditRole. Pour les autres rôles, l'implémentation renvoie un QVariantinvalide (construit par défaut).
Voir également Qt::ItemDataRole, setData() et headerData().
[override virtual] bool QRangeModel::dropMimeData(const QMimeData *data, Qt::DropAction action, int row, int column, const QModelIndex &parent)
Réimplémente : QAbstractItemModel::dropMimeData(const QMimeData *data, Qt::DropAction action, int row, int column, const QModelIndex &parent).
[override virtual protected] bool QRangeModel::event(QEvent *event)
Réimplémente : QObject::event(QEvent *e).
[override virtual protected] bool QRangeModel::eventFilter(QObject *object, QEvent *event)
Réimplémente : QObject::eventFilter(QObject *watched, QEvent *event).
[override virtual] void QRangeModel::fetchMore(const QModelIndex &parent)
Réimplémente : QAbstractItemModel::fetchMore(const QModelIndex &parent).
[override virtual] Qt::ItemFlags QRangeModel::flags(const QModelIndex &index) const
Réimplémente : QAbstractItemModel::flags(const QModelIndex &index) const.
Renvoie les drapeaux de l'élément pour l'adresse index donnée.
L'implémentation renvoie une combinaison de drapeaux qui activent l'élément (ItemIsEnabled) et permettent de le sélectionner (ItemIsSelectable). Pour les modèles fonctionnant sur une plage avec des données mutables, elle définit également l'indicateur qui permet à l'élément d'être modifiable (ItemIsEditable).
Voir également Qt::ItemFlags.
[override virtual] bool QRangeModel::hasChildren(const QModelIndex &parent = QModelIndex()) const
Réimplémente : QAbstractItemModel::hasChildren(const QModelIndex &parent) const.
[override virtual] QVariant QRangeModel::headerData(int section, Qt::Orientation orientation, int role = Qt::DisplayRole) const
Réimplémente : QAbstractItemModel::headerData(int section, Qt::Orientation orientation, int role) const.
Renvoie les données pour les role et section donnés dans l'en-tête avec le orientation spécifié.
Pour les en-têtes horizontaux, le numéro de section correspond au numéro de colonne. De même, pour les en-têtes verticaux, le numéro de section correspond au numéro de ligne.
Pour l'en-tête horizontal et le Qt::DisplayRole role , les modèles qui opèrent sur une plage utilisant un tableau comme type de ligne renvoient section. Si le type de ligne est un tuple, l'implémentation renvoie le nom du type à section. Pour les lignes de type gadget ou QObject, cette fonction renvoie le nom de la propriété à l'indice section.
Pour l'en-tête vertical, cette fonction renvoie toujours le résultat de l'implémentation par défaut à QAbstractItemModel.
Voir également Qt::ItemDataRole, setHeaderData() et QHeaderView.
[override virtual] QModelIndex QRangeModel::index(int row, int column, const QModelIndex &parent = {}) const
Réimplémente : QAbstractItemModel::index(int row, int column, const QModelIndex &parent) const.
Renvoie l'index de l'élément de modèle à row et column dans parent.
La transmission d'un parent valide produit un index non valide pour les modèles qui opèrent sur des plages de listes et de tableaux.
Voir aussi parent().
[override virtual] bool QRangeModel::insertColumns(int column, int count, const QModelIndex &parent = {})
Réimplémente : QAbstractItemModel::insertColumns(int column, int count, const QModelIndex &parent).
Insère count colonnes vides avant l'élément à column dans toutes les lignes de la plage à parent. Renvoie true en cas de succès ; sinon, renvoie false.
Remarque : un type de ligne à taille dynamique doit fournir une fonction membre insert(const_iterator, size_t, value_type).
Pour les modèles opérant sur une plage en lecture seule, ou sur une plage avec un type de ligne de taille statique (comme un tuple, un tableau ou une structure), cette implémentation ne fait rien et renvoie false immédiatement. C'est toujours le cas pour les modèles d'arbres.
[override virtual] bool QRangeModel::insertRows(int row, int count, const QModelIndex &parent = {})
Réimplémente : QAbstractItemModel::insertRows(int row, int count, const QModelIndex &parent).
Insère count lignes vides avant la ligne donnée row dans la plage à parent. Renvoie true en cas de succès ; sinon, renvoie false.
Remarque : la plage doit être dimensionnée de manière dynamique et fournir une fonction membre insert(const_iterator, size_t, value_type).
Pour les modèles fonctionnant sur une plage en lecture seule ou de taille statique (comme un tableau), cette implémentation ne fait rien et renvoie false immédiatement.
Remarque : pour les plages dont le type de colonne est de taille dynamique, la colonne doit fournir une fonction membre resize(size_t).
[override virtual] QMap<int, QVariant> QRangeModel::itemData(const QModelIndex &index) const
Réimplémente : QAbstractItemModel::itemData(const QModelIndex &index) const.
Renvoie une carte contenant les valeurs de tous les rôles prédéfinis dans le modèle pour l'élément à l'adresse index donnée.
Si le type d'élément pour ce index est un conteneur associatif qui renvoie de int, Qt::ItemDataRole, ou QString à QVariant, les données de ce conteneur sont renvoyées.
Si le type d'élément est un gadget ou une sous-classe de QObject, les valeurs des propriétés correspondant à role name sont renvoyées.
Si l'élément n'est pas un conteneur associatif, un gadget ou une sous-classe QObject, l'implémentation de la classe de base est appelée.
Voir aussi setItemData(), Qt::ItemDataRole, et data().
[override virtual] QModelIndexList QRangeModel::match(const QModelIndex &start, int role, const QVariant &value, int hits, Qt::MatchFlags flags) const
Réimplémente : 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
Réimplémente : QAbstractItemModel::mimeData(const QModelIndexList &indexes) const.
[override virtual] QStringList QRangeModel::mimeTypes() const
Réimplémente : QAbstractItemModel::mimeTypes() const.
[override virtual] bool QRangeModel::moveColumns(const QModelIndex &sourceParent, int sourceColumn, int count, const QModelIndex &destinationParent, int destinationColumn)
Réimplémente : QAbstractItemModel::moveColumns(const QModelIndex &sourceParent, int sourceColumn, int count, const QModelIndex &destinationParent, int destinationChild).
Déplace les colonnes de count commençant par la colonne donnée sourceColumn sous le parent sourceParent vers la colonne destinationColumn sous le parent destinationParent.
Renvoie true si les colonnes ont été déplacées avec succès ; sinon, renvoie false.
[override virtual] bool QRangeModel::moveRows(const QModelIndex &sourceParent, int sourceRow, int count, const QModelIndex &destinationParent, int destinationRow)
Réimplémente : QAbstractItemModel::moveRows(const QModelIndex &sourceParent, int sourceRow, int count, const QModelIndex &destinationParent, int destinationChild).
Déplace les lignes de count commençant par sourceRow sous le parent sourceParent vers la ligne destinationRow sous le parent destinationParent.
Renvoie true si les lignes ont été déplacées avec succès ; sinon, renvoie false.
[override virtual] void QRangeModel::multiData(const QModelIndex &index, QModelRoleDataSpan roleDataSpan) const
Réimplémente : QAbstractItemModel::multiData(const QModelIndex &index, QModelRoleDataSpan roleDataSpan) const.
[override virtual] QModelIndex QRangeModel::parent(const QModelIndex &child) const
Réimplémente : QAbstractItemModel::parent(const QModelIndex &index) const.
Renvoie le parent de l'élément à l'indice child.
Cette fonction produit toujours un index invalide pour les modèles qui opèrent sur des plages de listes et de tableaux. Pour les modèles opérant sur un arbre, cette fonction renvoie l'index de l'élément de ligne renvoyé par l'implémentation parent() du protocole de traversée de l'arbre.
Voir aussi index() et hasChildren().
[override virtual] bool QRangeModel::removeColumns(int column, int count, const QModelIndex &parent = {})
Réimplémente : QAbstractItemModel::removeColumns(int column, int count, const QModelIndex &parent).
Supprime count colonnes de l'élément situé à column sur toutes les lignes de la plage située à parent. Renvoie true en cas de succès, sinon false.
Remarque : un type de ligne à taille dynamique doit fournir une fonction membre erase(const_iterator, size_t).
Pour les modèles opérant sur une plage en lecture seule, ou sur une plage avec un type de ligne de taille statique (comme un tuple, un tableau ou une structure), cette implémentation ne fait rien et renvoie false immédiatement. C'est toujours le cas pour les modèles d'arbres.
[override virtual] bool QRangeModel::removeRows(int row, int count, const QModelIndex &parent = {})
Réimplémente : QAbstractItemModel::removeRows(int row, int count, const QModelIndex &parent).
Supprime count lignes de la plage à parent, en commençant par row. Renvoie true en cas de succès, sinon false.
Remarque : la plage doit être dimensionnée de manière dynamique et fournir une fonction membre erase(const_iterator, size_t).
Pour les modèles opérant sur une plage en lecture seule ou de taille statique (comme un tableau), cette implémentation ne fait rien et renvoie false immédiatement.
[override virtual protected slot] void QRangeModel::resetInternalData()
Réimplémente : QAbstractItemModel::resetInternalData().
[override virtual] QHash<int, QByteArray> QRangeModel::roleNames() const
Réimplémente : QAbstractItemModel::roleNames() const.
Remarque : il est possible de surcharger cette fonction dans une sous-classe de QRangeModel, mais cela risque d'altérer le comportement de la propriété.
Note : Fonction Getter pour la propriété roleNames.
Voir aussi setRoleNames().
[override virtual] int QRangeModel::rowCount(const QModelIndex &parent = {}) const
Réimplémente : QAbstractItemModel::rowCount(const QModelIndex &parent) const.
Renvoie le nombre de lignes sous l'index parent donné. Il s'agit du nombre d'éléments dans la plage racine pour un indice parent non valide.
Si l'index parent est valide, cette fonction renvoie toujours 0 pour les modèles qui opèrent sur des plages de listes et de tableaux. Pour les arbres, cette fonction renvoie la taille de la plage renvoyée par l'implémentation childRows() du protocole de traversée des arbres.
Voir aussi columnCount(), insertRows() et hasChildren().
[override virtual] bool QRangeModel::setData(const QModelIndex &index, const QVariant &data, int role = Qt::EditRole)
Réimplémente : QAbstractItemModel::setData(const QModelIndex &index, const QVariant &value, int role).
Définit les données de role pour l'élément à index à data.
Si le type d'élément de index est un conteneur associatif qui permet de faire correspondre int, Qt::ItemDataRole ou QString à QVariant, alors data est stocké dans ce conteneur pour la clé spécifiée par role.
Si l'élément est un gadget ou QObject, alors data est écrit dans la propriété de l'élément correspondant à l'entrée role dans le mappage roleNames(). La fonction renvoie true si une propriété a été trouvée et si data a stocké une valeur pouvant être convertie dans le type requis, sinon elle renvoie false.
Dans le cas contraire, cette implémentation attribue la valeur de data à l'élément situé à l'adresse index dans l'intervalle de Qt::DisplayRole et Qt::EditRole, et renvoie true. Pour les autres rôles, l'implémentation renvoie false.
Pour les modèles fonctionnant sur une plage en lecture seule ou sur une colonne en lecture seule dans un type de ligne qui implémente the C++ tuple protocol, cette implémentation renvoie immédiatement false.
Voir aussi data().
[override virtual] bool QRangeModel::setHeaderData(int section, Qt::Orientation orientation, const QVariant &data, int role = Qt::EditRole)
Réimplémente : QAbstractItemModel::setHeaderData(int section, Qt::Orientation orientation, const QVariant &value, int role).
Voir également headerData().
[override virtual] bool QRangeModel::setItemData(const QModelIndex &index, const QMap<int, QVariant> &data)
Réimplémente : QAbstractItemModel::setItemData(const QModelIndex &index, const QMap<int, QVariant> &roles).
Si le type d'élément de ce site index est un conteneur associatif qui va de int ou Qt::ItemDataRole à QVariant, les entrées de data sont stockées dans ce conteneur. Si le conteneur associatif va de QString à QVariant, seules les valeurs de data pour lesquelles il existe une correspondance dans la table role names sont stockées.
Si le type d'élément est un gadget ou une sous-classe de QObject, les propriétés qui correspondent à role name prennent la valeur correspondante dans data.
Les rôles pour lesquels il n'existe pas d'entrée dans data ne sont pas modifiés.
Pour les types d'éléments qui peuvent être copiés, cette implémentation est transactionnelle et renvoie la valeur "vrai" si toutes les entrées de data ont pu être stockées. Si une entrée n'a pas pu être mise à jour, le conteneur d'origine n'est pas modifié du tout et la fonction renvoie un message faux.
Si l'élément n'est pas un conteneur associatif, un gadget ou une sous-classe de QObject, la fonction appelle l'implémentation de la classe de base, qui appelle setData() pour chaque entrée de data.
Voir également itemData(), setData() et Qt::ItemDataRole.
[override virtual] QModelIndex QRangeModel::sibling(int row, int column, const QModelIndex &index) const
Réimplémente : QAbstractItemModel::sibling(int row, int column, const QModelIndex &index) const.
Renvoie le frère ou la sœur à row et column pour l'élément à index, ou un QModelIndex invalide s'il n'y a pas de frère ou de sœur à cet endroit.
Cette implémentation est beaucoup plus rapide que de passer par parent() de index.
Voir aussi index(), QModelIndex::row() et QModelIndex::column().
[override virtual] void QRangeModel::sort(int column, Qt::SortOrder order = Qt::AscendingOrder)
Réimplémente : QAbstractItemModel::sort(int column, Qt::SortOrder order).
[override virtual] QSize QRangeModel::span(const QModelIndex &index) const
Réimplémente : QAbstractItemModel::span(const QModelIndex &index) const.
[override virtual] Qt::DropActions QRangeModel::supportedDragActions() const
Réimplémente : QAbstractItemModel::supportedDragActions() const.
[override virtual] Qt::DropActions QRangeModel::supportedDropActions() const
Réimplémente : 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.