QRangeModel Class
QRangeModel implémente l'interface « QAbstractItemModel » pour n'importe quelle plage en C++. En savoir plus...
| 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 de : | QAbstractItemModel |
Remarque : 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 } |
(since 6.12) enum class | DropOperation { DontDrop, Automatic, OverwriteAndIgnore, OverwriteAndExtend, InsertAsSiblings, InsertAsChildren } |
| enum class | RowCategory { Default, MultiRoleItem } |
Propriétés
|
|
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 | resetSortCollator() |
| void | resetSortRole() |
| void | resetSupportedDragActions() |
| void | resetSupportedDropActions() |
| void | setAutoConnectPolicy(QRangeModel::AutoConnectPolicy policy) |
| void | setRoleNames(const QHash<int, QByteArray> &names) |
| void | setSortCollator(const QCollator &collator) |
| void | setSortRole(int role) |
| void | setSupportedDragActions(Qt::DropActions actions) |
| void | setSupportedDropActions(Qt::DropActions actions) |
| QCollator | sortCollator() const |
| int | sortRole() const |
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() |
| void | sortCollatorChanged(const QCollator &collator) |
| void | sortRoleChanged(int role) |
| void | supportedDragActionsChanged(Qt::DropActions actions) |
| void | supportedDropActionsChanged(Qt::DropActions actions) |
Fonctions protégées réimplémentées
| virtual bool | event(QEvent *event) override |
| virtual bool | eventFilter(QObject *object, QEvent *event) override |
Slots protégés
| virtual void | resetInternalData() override |
Description détaillée
QRangeModel permet de mettre les données de n'importe quel type C++ itérable de manière séquentielle à la disposition du framework modèle/vue de Qt. Cela facilite l'affichage des structures de données existantes dans les vues d'éléments « Qt Widgets » et « Qt Quick », et permet à l'utilisateur de l'application de manipuler les données à l'aide d'une interface utilisateur 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 renvoyé 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.
La plage doit être fournie lors de la construction du modèle et peut l’être par valeur, par wrapper de référence ou par pointeur. La manière dont le modèle a été construit détermine si les modifications apportées via l’API du modèle modifieront les données d’origine. Utilisez QRangeModelAdapter pour construire implicitement un modèle tout en bénéficiant d’un accès direct, sécurisé au niveau des types et pratique au modèle en tant que plage.
Lorsqu’il est construit par valeur, le modèle crée une copie de la plage, et les API d’ 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 surveillées en se connectant aux signaux émis par le modèle, tels que dataChanged().
Pour que les modifications apportées au modèle affectent la plage d’origine, fournissez cette dernière soit par pointeur :
QRangeModel model(&numbers);ou via 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 conteneurs C++ standard resize(), insert(), erase(), en plus de déréférencer 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 il opère ne doit plus être modifiée directement. Les vues du modèle ne seraient pas informées de ces modifications, et les changements structurels risqueraient de corrompre les instances d’ QPersistentModelIndex s gérées par le modèle. 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 ne soit supprimée que lorsque tous les clients en ont fini avec elle.
auto shared_numbers = std::make_shared<std::vector<int>>(numbers);
QRangeModel model(shared_numbers);QRangeModel prend en charge à la fois les pointeurs partagés et les pointeurs uniques.
En lecture seule ou modifiable
Pour les plages qui sont des objets const, pour lesquelles l’accès renvoie 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 qui ne font rien et renvoient ` false`. Dans l’exemple utilisant ` std::array`, le modèle ne peut ni ajouter ni supprimer de 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 la modification des valeurs dans la vue de liste. En rendant le tableau `const`, 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 de l’élément est de type const, comme dans
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 de type `const`, il n’est alors pas non plus possible de supprimer ou d’insérer des colonnes et des lignes via l’API ` QAbstractItemModel `. Pour un contrôle plus fin, 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. En fonction du type de ces éléments de ligne, QRangeModel expose la plage sous forme de liste, de tableau ou d’arborescence.
Si les éléments de ligne sont des valeurs simples, la plage est alors représentée sous forme de 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 alors représentée sous forme de 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 conteneurs C++ standard resize(), insert(), erase(), alors les colonnes peuvent être ajoutées et supprimées via insertColumns() et removeColumns(). Toutes les lignes doivent comporter le même nombre de colonnes.
Structures et gadgets en tant que lignes
Si le type de ligne implémente the C++ tuple protocol, alors la plage est représentée sous la forme d’un tableau comportant 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 doté de 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 de sous-classes de ` QObject ` permet de lier des propriétés ou de disposer de signaux de notification de modification. Cependant, l'utilisation d'instances de ` QObject ` pour les éléments entraîne une surcharge mémoire importante.
L'utilisation de gadgets ou d'objets Qt est plus pratique et peut s'avérer plus flexible que l'implémentation du protocole tuple. Ces types sont également directement accessibles depuis QML. Cependant, l'accès via le système de propriétés entraîne une certaine surcharge à l'exécution. Pour les modèles où les performances sont cruciales, envisagez d'implémenter le protocole tuple afin de générer le code d'accès lors de la compilation.
Éléments à rôles multiples
Le type des éléments sur lesquels portent 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 comporter différents types d’éléments pour différentes colonnes, comme dans le cas « 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 davantage de flexibilité).
Conteneurs associatifs à rôles multiples
Si l’élément est un conteneur associatif utilisant int, Qt::ItemDataRole ou QString comme type de clé, et QVariant comme type mappé, alors QRangeModel interprète ce conteneur comme le stockage des données pour plusieurs rôles. Les fonctions ` data()` et ` setData()` renvoient et modifient la valeur mappée dans le conteneur, tandis que ` setItemData()` modifie toutes les valeurs fournies, ` itemData()` renvoie toutes les valeurs stockées et ` clearItemData()` efface l’intégralité du 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);Les types de données les plus efficaces à utiliser comme clé sont Qt::ItemDataRole ou int. Lorsque vous utilisez int, la fonction itemData() renvoie le conteneur tel quel et n’a pas besoin de créer une copie des données.
Gadgets et objets en tant qu’éléments à rôles multiples
Les gadgets et les types de QObject peuvent également être représentés en tant qu’éléments à rôles multiples. Les propriétés de ces éléments seront utilisées pour le rôle auquel correspond l’ name of a role. Si tous les éléments sont du même type de gadget ou de QObject, alors 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 READ colorName)
Q_PROPERTY(QColor decoration READ decoration)
Q_PROPERTY(QString toolTip READ toolTip)
public:
ColorEntry(const QString &color = {})
: m_colorName(color)
{}
QString colorName() const
{
return m_colorName;
}
QColor decoration() const
{
return QColor::fromString(m_colorName);
}
QString toolTip() const
{
return QColor::fromString(m_colorName).name();
}
private:
QString m_colorName;
};Lorsqu’ils sont utilisés 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 sous forme de lignes à plusieurs colonnes, chaque propriété étant représentée par une colonne distincte. Pour forcer la représentation d’un gadget en tant qu’élément à rôles multiples dans une liste, déclarez le gadget comme un type à rôles multiples en spécialisant QRoleModel::RowOptions, avec une variable membre static constexpr auto rowCategory définie sur MultiRoleItem.
class ColorEntry
{
Q_GADGET
Q_PROPERTY(QString display READ 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 encapsuler 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 passer par std::get:
ColorEntry firstEntry = std::get<0>(colors.at(0));ou bien 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, telles 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’arborescence. Les lignes qui sont des QObjects présenteront chaque propriété sous forme de colonne, à moins que le modèle QRangeModel::RowOptions ne soit spécialisé pour déclarer le type comme un élément à rôles multiples.
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 un QRangeModel à partir d’un pointeur ou d’un wrapper de référence de la plage. Sinon, la propriété des données devient ambiguë, et une copie de la plage continuerait à opérer sur les mêmes données de ligne réelles, ce qui entraînerait des effets secondaires inattendus.
Sous-classer 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é, puis appelez le constructeur de QRangeModel avec un wrapper de référence ou un pointeur vers ce membre. Cela encapsule correctement les données et évite tout 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 modifiant la plage. L’accès en lecture seule peut 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’arborescence, la liste des lignes enfants doit utiliser exactement la même représentation que l’arborescence elle-même. De plus, le type de ligne doit être de taille statique : il peut s’agir soit d’un type « gadget » ou « QObject », soit d’un type implémentant l’interface the C++ tuple protocol.
Pour représenter ces données sous forme d’arbre, QRangeModel doit être capable de parcourir la structure de données : pour toute ligne donnée, le modèle doit pouvoir récupérer la ligne parente, ainsi que l’intervalle optionnel des lignes enfants. Ces fonctions de parcours peuvent être fournies implicitement via le type de ligne, ou via un type de protocole explicite.
Protocole implicite de traversée d’arbre
class TreeRow;
using Tree = std::vector<TreeRow>;L’arbre lui-même est un vecteur de valeurs de type ` TreeRow `. Voir Tree Rows as pointers or values pour savoir s’il vaut mieux utiliser des valeurs ou des pointeurs vers des é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 defaultedLa classe de ligne peut être de n’importe quel type à taille fixe décrit ci-dessus : un type implémentant le protocole tuple, un gadget ou un ` QObject`. Dans cet exemple, nous utilisons un gadget.
Chaque élément de ligne doit conserver un pointeur vers la ligne parente, ainsi qu’une plage facultative de lignes enfants. Cette plage doit être identique à la structure de plage utilisée pour l’arbre lui-même.
Rendre le type de ligne constructible 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 de ` 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’arborescence peut alors être implémenté sous forme de fonctions membres du type de données « row ». Une fonction const parentRow() doit renvoyer un pointeur vers un élément de ligne ; et la fonction childRows() doit renvoyer une référence à un const std::optional pouvant contenir la plage optionnelle d’éléments enfants.
Ces deux fonctions suffisent pour que le modèle puisse parcourir l’arbre en tant que structure de données en lecture seule. Pour permettre à l’utilisateur de modifier les données d’une vue, et au modèle d’implémenter des API de modification telles que ` insertRows()`, ` removeRows()` et ` moveRows()`, nous devons implémenter 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 de childRows() pour déplacer ou insérer des lignes dans une branche existante de l’arborescence, 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 de la ligne.
Remarque : le modèle effectue les opérations suivantes en étapes distinctes : définir le parent d’une ligne, supprimer cette ligne de l’ancien parent et l’ajouter à la liste des enfants du nouveau parent. Cela permet de conserver une interface de protocole légère.
...
// 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 fonction d’aide ` addChild() ` nous offre un moyen pratique de construire l’état initial de l’arborescence.
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` 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 distincte
Le protocole de parcours d’arbre peut également être implémenté 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{});Lignes de l’arbre sous forme de pointeurs ou de valeurs
Le type des nœuds de la plage de données peut être soit une valeur, soit un pointeur. Dans le code ci-dessus, nous avons utilisé les nœuds de l’arborescence comme des valeurs dans un vecteur, ce qui é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 toutes les références lorsqu’il doit réallouer de l’espace de stockage, ou lors de l’insertion ou de la suppression d’éléments. Cela affecte le pointeur vers l’élément parent, qui correspond à l’emplacement de la ligne parente au sein du vecteur. S'assurer que ce parent (et les instances d'QPersistentModelIndex s faisant référence aux éléments qu'il contient) reste valide peut entraîner une surcharge de performances considérable. L'implémentation de QRangeModel doit partir du principe que toutes les références au plage deviennent invalides lors de la modification de celle-ci.
Comme alternative, nous pouvons également utiliser une plage de pointeurs de ligne comme type d’arbre :
struct TreeRow;
using Tree = std::vector<TreeRow *>;Dans ce cas, nous devons allouer explicitement toutes les instances de `TreeRow` à l'aide de l'opérateur ` new`, et implémenter le destructeur pour ` delete ` tous les éléments du vecteur des enfants.
struct TreeRow
{
Q_GADGET
public:
TreeRow(const QString&value = {})
: m_value(value)
{}
~TreeRow()
{
if (m_children)
qDeleteAll(*m_children);
}
// déplacement uniquement
TreeRow(TreeRow&&) = default;
TreeRow&operator=(TreeRow&&) = default;
// fonction d'aide au remplissage
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");Avant de pouvoir construire un modèle représentant ces données sous forme d'arbre, nous devons également implémenter le protocole de traversée de l'arbre.
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(). De plus, si le modèle détient la propriété des données, il supprimera également toutes les lignes de niveau supérieur lors de sa destruction. Notez que dans cet exemple, nous déplaçons l’arborescence dans le modèle ; nous n’avons donc plus besoin d’effectuer d’opérations sur celle-ci. Le `QRangeModel`, lorsqu’il est construit en y déplaçant des données d’arborescence 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 entraîne une certaine surcharge liée à l’allocation et à la gestion de la mémoire. Cependant, les références aux éléments de ligne restent stables, même lorsqu’ils sont déplacés au sein de la plage ou lorsque celle-ci est réalloué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 entre performances et surcoût mémoire. La meilleure option dépend du cas d’utilisation précis et de la structure de données employée.
Personnalisation par spécialisation de modèles
QRangeModel déclare deux types de modèles imbriqués que vous pouvez spécialiser pour remplacer le comportement par défaut.
Le modèle ` RowOptions `, que nous avons déjà présenté plus haut, sert à personnaliser les fonctionnalités spécifiques au type de ligne, telles que les données d’en-tête, ou celles qui doivent s’appliquer de manière uniforme à tous les éléments d’une ligne, comme les indicateurs par défaut. Le modèle ` ItemAccess ` permet de personnaliser le comportement spécifique à un type d’élément, comme la lecture ou l’écriture des données de rôle.
Ces deux modèles doivent toujours être spécialisés pour le type sous-jacent ; ainsi, même si la plage contient des lignes de type Row en tant que std::unique_ptr<Row>, ou des éléments de type Item en tant que std::shared_ptr<Item>, la spécialisation doit porter sur Row et Item.
template <>
struct QRangeModel::ItemAccess<ColorEntry>
{
...
};
std::vector<std::shared_ptr<ColorEntry>> colors;
// ...
QRangeModel model(colors);Remarque : en C++, vous ne devez jamais spécialiser des modèles que pour des types dont vous êtes propriétaire, et non pour des types standard ou Qt. Créez des sous-classes ou des agrégats pour les types que vous ne contrôlez pas si vous avez besoin de personnaliser le comportement de ces types. Notez qu’un alias de type n’est pas un type distinct, et que vous ne devez pas spécialiser de modèles pour des types alias. Il est toutefois autorisé de créer une spécialisation d’un conteneur standard ou Qt avec un type dont vous êtes propriétaire, tel qu’un ` std::vector<MyGadget>`.
Indicateurs spécifiques aux lignes et aux éléments
L’implémentation par défaut de ` flags()` renvoie une combinaison des indicateurs ` Qt::ItemIsSelectable`, ` Qt::ItemIsEnabled` et — sauf pour les éléments situés dans la colonne 0 d’un modèle d’arborescence — ` Qt::ItemNeverHasChildren`. Les indicateurs ` Qt::ItemIsEditable ` et ` Qt::ItemIsDropEnabled ` sont activés pour tous les éléments des modèles qui ne sont pas en lecture seule, et ` Qt::ItemIsDragEnabled ` est activé tant que le modèle prend en charge au moins une ` mime type`.
Pour personnaliser le comportement par défaut de tous les éléments d’une ligne, spécialisez le modèle RowOptions. Pour accéder aux données des indicateurs par élément, spécialisez le modèle ItemAccess. Vous pouvez faire les deux : RowOptions permet de définir des indicateurs communs à tous les éléments d’une ligne, tandis que ItemAccess permet de définir des indicateurs pour les éléments basés sur un type spécifique.
Gestion du glisser-déposer
Depuis Qt 6.12, QRangeModel implémente la fonction virtuelle ` flags()` pour définir le drapeau ` Qt::ItemIsDragEnabled ` pour tous les éléments valides d’un modèle, à condition que ce dernier prenne en charge au moins un ` mime type`. Il s’agit du comportement par défaut, car ` QAbstractItemModel ` fournit le type MIME interne à Qt « application/x-qabstractitemmodeldatalist ». De plus, l’indicateur « Qt::ItemIsDropEnabled » est activé pour les éléments d’un tel modèle, à condition que ce dernier ne soit pas en lecture seule. Cela inclut l’élément inexistant à l’index invalide, ce qui permet aux utilisateurs de déposer des données dans des zones vides d’une vue afin de les ajouter à la fin.
La prise en charge de types MIME supplémentaires peut être mise en œuvre sans créer de sous-classe de QRangeModel ni redéfinir les fonctions virtuelles correspondantes. QRangeModel détectera et utilisera les fonctions des modèles de personnalisation ItemAccess et RowOptions pour encoder les lignes ou les éléments en mime data, et pour les decode mime data en séquences de lignes ou d’éléments. Ces fonctions de personnalisation peuvent opérer directement sur les types de lignes et d’éléments, sans passer par QModelIndex et QVariant.
De cette manière, le code de sérialisation des données peut être sûr du point de vue des types et peut rester associé à l’implémentation du type utilisé pour stocker les données.
De plus, ` supportedDragActions ` et ` supportedDropActions ` sont des propriétés pouvant être configurées pour chaque instance de `QRangeModel`.
Sujets avancés en C++
Le protocole de tuples en C++
Comme le montre l’exemple numberNames ci-dessus, le type de ligne peut être un tuple, et en fait n’importe quel type implémentant le protocole de tuple. Ce protocole est implémenté en spécialisant std::tuple_size et std::tuple_element, et en surchargeant la fonction non qualifiée get. Procédez ainsi pour votre type de ligne personnalisé afin de rendre les données structurées existantes accessibles au framework modèle/vue de 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 d’édition, et la fonction « setData() » ne fait rien et renvoie « false ». Pour ` summary ` et ` rating `, l’implémentation renvoie la même valeur de catégorie que le livre ; ainsi, lorsque ` get ` est appelé avec une référence modifiable vers un ` Book`, il renvoie une référence modifiable de la variable correspondante. Le modèle rend ces colonnes modifiables, tant pour l’utilisateur que pour l’accès programmatique.
Remarque : l’implémentation de ` get ` ci-dessus nécessite C++23.
Considérations relatives à la compatibilité binaire
QRangeModel n'est pas une classe de modèle. Le passage d'instances de QRangeModel (par pointeur ou par référence, comme pour toutes les classes de la bibliothèque « QObject ») via les API de la bibliothèque, ou le stockage de QRangeModel par valeur dans une classe publique d'une bibliothèque, ne présente aucun risque.
Cependant, le constructeur de QRangeModel est un modèle et est inline, et l’implémentation interne, spécialisée en fonction du 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 inline d’une API de bibliothèque. Cela entraîne des violations de l’ODR et pourrait rompre la compatibilité binaire de cette bibliothèque si la version de Qt utilisée pour sa compilation diffère de celle utilisée pour la compilation d’une application utilisant cette bibliothèque.
Les nouvelles implémentations optimisées des fonctions virtuelles introduites dans les versions ultérieures de Qt pourraient également ne pas être utilisées si QRangeModel détecte que l’implémentation a été compilée avec une version plus ancienne de Qt. Par exemple, les implémentations de ` sort()` et ` match()` sont nouvelles dans Qt 6.12, mais ne seront pas appelées par une application compilée avec Qt 6.11, même si la bibliothèque Qt utilisée est Qt 6.12. Pour bénéficier de ces nouvelles redéfinitions, recompilez votre application.
Voir également QRangeModelAdapter, QAbstractItemModel, QStandardItemModel et 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 modifiés des propriétés au signal dataChanged() du modèle. Seules les propriétés correspondant à l'une des valeurs de 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 concernées sont connectés automatiquement, pour tous les éléments de l’ QObject. Cela inclut les éléments « QObject » ajoutés aux lignes et colonnes nouvellement insérées. |
QRangeModel::AutoConnectPolicy::OnRead | 2 | Les signaux des propriétés concernées sont connectés la première fois que le modèle lit la propriété. |
La surcharge mémoire liée à la création de connexions automatiques peut être importante. Une connexion automatique complète ne nécessite aucune gestion supplémentaire en dehors de la connexion elle-même, mais chaque connexion occupe de la mémoire, et connecter toutes les propriétés de tous les objets peut s’avérer très coûteux, en particulier si seules quelques propriétés d’un sous-ensemble d’objets sont amenées à changer.
La politique de connexion « OnRead » n'établit pas de connexion avec les objets ou les propriétés qui ne sont jamais lus (par exemple, qui ne sont jamais affichés dans une vue), mais le fait de se souvenir des connexions établies implique une certaine charge administrative et une augmentation imprévisible de l'utilisation de la mémoire au fil du temps. Par exemple, le défilement vers le bas d'une longue liste d'éléments peut facilement entraîner la création de milliers de nouvelles connexions.
Cette énumération a été introduite dans Qt 6.11.
Voir également autoConnectPolicy et roleNames().
[since 6.12] enum class QRangeModel::DropOperation
Cette énumération définit la manière dont les données décodées dans une personnalisation de la méthode ` dropMimeData()` sont écrites dans le modèle.
| Constante | Valeur | Description |
|---|---|---|
QRangeModel::DropOperation::DontDrop | 0 | Les données ne doivent pas être ajoutées au modèle. |
QRangeModel::DropOperation::Automatic | 1 | Qt détermine la manière dont les données sont ajoutées au modèle. |
QRangeModel::DropOperation::OverwriteAndIgnore | 2 | Remplacer l'élément sur lequel les données ont été déposées ainsi que les éléments suivants, et ignorer toutes les données déposées qui ne rentrent pas. |
QRangeModel::DropOperation::OverwriteAndExtend | 3 | Remplacer l'élément sur lequel les données ont été déposées ainsi que les éléments suivants, et agrandir le modèle pour y intégrer toutes les données déposées. |
QRangeModel::DropOperation::InsertAsSiblings | 4 | Insérer toutes les données déposées en tant qu’éléments frères de l’élément sur lequel elles ont été déposées. |
QRangeModel::DropOperation::InsertAsChildren | 5 | Insérer toutes les données déposées en tant qu’enfants de l’élément sur lequel elles ont été déposées. |
Une personnalisation de ` dropMimeData()` peut renvoyer une valeur booléenne à la place ; dans ce cas, ` false ` correspond à la valeur `DontDrop`, et ` true ` à `Automatic`.
Cette énumération a été introduite dans Qt 6.12.
Voir également canDropMimeData() et dropMimeData().
enum class QRangeModel::RowCategory
Cette énumération décrit la manière dont l'QRangeModel e doit présenter les éléments de la plage à partir de laquelle il a été construit.
| Constante | Valeur | Description |
|---|---|---|
QRangeModel::RowCategory::Default | 0 | QRangeModel détermine la manière dont les lignes sont présentées. |
QRangeModel::RowCategory::MultiRoleItem | 1 | QRangeModel présentera les éléments dotés d’un méta-objet comme des éléments à rôles multiples, même lorsqu’ils sont utilisés dans un intervalle unidimensionnel. |
Spécialisez le modèle ` RowOptions ` pour votre type, puis 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 lorsque le modèle se connecte automatiquement aux notifications de modification de propriété.
Si QRangeModel opère sur une structure de données contenant le même type de sous-classe d’ 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 de QObject, cette opération est effectuée pour chaque colonne, en établissant un mappage vers la propriété Qt::DisplayRole. Pour les éléments, cela s’applique aux propriétés qui correspondent à l’une des propriétés de role names.
Par défaut, la valeur de cette propriété est None, ce qui signifie qu’aucune connexion de ce type n’est établie. La modification de la valeur de cette propriété rompt systématiquement toutes les connexions existantes.
Remarque : les connexions ne sont ni rompues ni créées si des objets QObject de la structure de données sur laquelle QRangeModel opère sont remplacés.
Cette énumération a été introduite dans Qt 6.11.
Fonctions d’accès :
| QRangeModel::AutoConnectPolicy | autoConnectPolicy() const |
| void | setAutoConnectPolicy(QRangeModel::AutoConnectPolicy policy) |
Signal de notification :
| void | autoConnectPolicyChanged(QRangeModel::AutoConnectPolicy policy) |
Voir également ` 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éta-objet (c'est-à-dire s'il s'agit d'un gadget ou d'une sous-classe de ` QObject `), alors cette propriété contient les noms des propriétés de ce type, mappés aux valeurs de ` Qt::ItemDataRole ` à partir de ` Qt::UserRole ` et au-delà. De plus, un rôle « modelData » donne accès à l’instance du gadget ou de l’ QObject.
Pour remplacer ce comportement par défaut, définissez explicitement cette propriété sur un mappage non vide. Définir cette propriété sur un mappage vide ou utiliser la méthode 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() |
Signal Notifier :
| void | roleNamesChanged() |
Voir également QAbstractItemModel::roleNames().
[since 6.12] sortCollator : QCollator
Cette propriété contient le collateur qui sera utilisé lors du tri du modèle
La valeur par défaut de cette propriété est un collateur de type « QCollator » pour la locale C. Le tri ne tiendra pas compte de la locale et sera sensible à la casse. La définition d’un collateur rendra le tri sensible à la locale.
Cette énumération a été introduite dans Qt 6.12.
Fonctions d'accès :
| QCollator | sortCollator() const |
| void | setSortCollator(const QCollator &collator) |
| void | resetSortCollator() |
Signal de notification :
| void | sortCollatorChanged(const QCollator &collator) |
Voir également ` sort()`, ` sortRole` et ` QSortFilterProxyModel`.
[since 6.12] sortRole : int
Cette propriété contient le rôle de données utilisé lors du tri des éléments.
La valeur par défaut est « Qt::DisplayRole ».
Cette énumération a été introduite dans Qt 6.12.
Fonctions d'accès :
| int | sortRole() const |
| void | setSortRole(int role) |
| void | resetSortRole() |
Signal de notification :
| void | sortRoleChanged(int role) |
Voir également sort(), sortCollator et QSortFilterProxyModel.
[since 6.12] supportedDragActions : Qt::DropActions
Cette propriété contient les actions de glisser-déposer prises en charge par ce modèle.
Les actions que le modèle ne peut pas prendre en charge, telles que le déplacement de données hors d’un modèle en lecture seule, seront supprimées lors de la définition des actions.
Remarque : il est possiblede redéfinir cette fonction dans une sous-classe de ` QRangeModel `, mais cela risque d'altérer le comportement de la propriété.
Cette énumération a été introduite dans Qt 6.12.
Fonctions d'accès :
| virtual Qt::DropActions | supportedDragActions() const override |
| void | setSupportedDragActions(Qt::DropActions actions) |
| void | resetSupportedDragActions() |
Signal de notification :
| void | supportedDragActionsChanged(Qt::DropActions actions) |
Voir également supportedDropActions.
[since 6.12] supportedDropActions : Qt::DropActions
Cette propriété contient les actions de glisser-déposer prises en charge par ce modèle.
Les modèles en lecture seule ne peuvent prendre en charge aucune action de glisser-déposer.
Remarque : il est possiblede redéfinir cette fonction dans une sous-classe de ` QRangeModel `, mais cela peut perturber le comportement de la propriété.
Cette énumération a été introduite dans Qt 6.12.
Fonctions d'accès :
| virtual Qt::DropActions | supportedDropActions() const override |
| void | setSupportedDropActions(Qt::DropActions actions) |
| void | resetSupportedDropActions() |
Signal de notification :
| void | supportedDropActionsChanged(Qt::DropActions actions) |
Voir aussi supportedDragActions.
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 contenues dans ` range`. L'range doit être un intervalle séquentiel pour lequel le compilateur trouve des surcharges de ` begin ` et ` end ` via la recherche dépendante des arguments, ou pour lequel ` std::begin ` et ` std::end ` sont implémentées. Si ` protocol ` est fourni, le modèle représentera alors l'intervalle sous forme d'arbre à l'aide de l'implémentation du protocole. L'instance du modèle devient un enfant de ` parent`.
L’ range peut être un pointeur ou un wrapper de référence ; dans ce cas, les API de modification du modèle (telles que setData() ou insertRow()) modifieront les données de l’instance de plage référencée. Si range est une valeur (ou a été déplacée dans le modèle), il faut alors se connecter aux signaux émis par le modèle pour réagir aux changements apportés aux données.
QRangeModel ne accédera pas à l’ range pendant sa construction. Il est donc autorisé de passer à ce constructeur un pointeur ou une référence vers un objet `range` qui n’est pas encore entièrement construit, par exemple lors de l’appel de ` subclassing QRangeModel`.
Si l’ range a été déplacé dans le modèle, alors la plage et toutes les données qu’elle contient seront détruites lors de la destruction du modèle.
Remarque : bien que le modèle ne prenne pas possession de l’objet `range` par ailleurs, vous ne devez pas modifier directement l’ 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 la synchronisation des utilisateurs du modèle (autres modèles ou vues) avec celui-ci, 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 plage sous-jacente tout en maintenant le modèle à jour.
Voir également QRangeModelAdapter.
[override virtual noexcept] QRangeModel::~QRangeModel()
Détruit l'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.
Si une personnalisation de ` ItemAccess ` est disponible pour le type d’élément stocké dans la plage, et si cette personnalisation implémente une fonction membre de classe ` canDropMimeData()` appropriée, alors cette implémentation appelle cette fonction et renvoie le résultat.
template <>
struct QRangeModel::ItemAccess<ColorEntry>
{
static bool canDropMimeData(const QMimeData *mimeData)
{
// ...
return true;
}
};Sinon, si une personnalisation de ` RowOptions ` est disponible pour le type de ligne de la plage avec une fonction membre de classe ` canDropMimeData()` appropriée, cette implémentation renvoie le résultat de l’appel de cette fonction.
template <>
struct QRangeModel::RowOptions<ColorEntry>
{
static bool canDropMimeData(const QMimeData *mimeData)
{
// ...
return true;
}
};Si aucune de ces personnalisations n’est disponible, cette implémentation renvoie alors le résultat de l’implémentation par défaut de ` QAbstractItemModel `.
Voir également Drag'n'drop handling, RowOptions::canDropMimeData(), ItemAccess::canDropMimeData(), dropMimeData(), mimeTypes() et mimeData().
[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 la plage à l'adresse index par une valeur construite par défaut.
Pour les modèles opérant sur une plage en lecture seule, ou sur une colonne en lecture seule d’un type de ligne implémentant ` 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 de type ` parent `.
Pour les modèles fonctionnant avec un type de ligne de taille statique, cette valeur renvoyée reste toujours la même tout au long de la durée de vie du modèle. Pour les modèles fonctionnant avec un type de ligne de taille dynamique, le modèle renvoie le nombre d’éléments de la première ligne, ou 0 si le modèle ne comporte aucune ligne.
Voir également ` 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'role donné pour la valeur comprise dans la plage référencée par l'index.
Si le type d’élément pour cet index est un conteneur associatif qui effectue un mappage depuis soit int, soit Qt::ItemDataRole, soit QString vers un QVariant, alors les données de rôle sont recherchées dans ce conteneur et renvoyées.
Si l’élément est un gadget ou un QObject, l’implémentation renvoie alors 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 ` QVariant` invalide (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).
Si une personnalisation de ` ItemAccess ` est disponible pour le type d’élément stocké dans la plage, et si cette personnalisation implémente une fonction membre de classe ` dropMimeData()` appropriée, alors cette implémentation appelle cette fonction et renvoie le résultat.
template <>
struct QRangeModel::ItemAccess<ColorEntry>
{
static bool dropMimeData(const QMimeData *mimeData, auto inserter)
{
QByteArray data = mimeData->data(mimeTypes().first());
if (data.isEmpty())
return false;
QTextStream stream(&data, QIODevice::ReadOnly);
while (!stream.atEnd()) {
QString colorName;
stream >> colorName;
inserter = ColorEntry(colorName);
}
return true;
}
};Sinon, si une personnalisation de ` RowOptions ` est disponible pour le type de ligne de la plage et comporte une fonction membre de classe ` dropMimeData()` appropriée, cette implémentation renvoie alors le résultat de l’appel à cette fonction.
template <>
struct QRangeModel::RowOptions<ColorEntry>
{
static bool dropMimeData(const QMimeData *mimeData, auto inserter)
{
const QByteArray data = mimeData->data(mimeTypes().first());
if (data.isEmpty())
return false;
QXmlStreamReader stream(data);
while (!stream.atEnd()) {
stream.readNext();
if (stream.isStartElement() && stream.name() == u"li"_s)
inserter = ColorEntry(stream.readElementText());
}
return true;
}
};Si aucune de ces personnalisations n’est disponible, cette implémentation renvoie alors le résultat de l’implémentation par défaut de ` QAbstractItemModel `.
Voir également Drag'n'drop handling, RowOptions::dropMimeData(), ItemAccess::dropMimeData(), canDropMimeData(), mimeTypes() et mimeData().
[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 indicateurs de l'élément pour l'index donné.
L’implémentation renvoie une combinaison d’indicateurs qui active l’élément (ItemIsEnabled) et permet de le sélectionner (ItemIsSelectable). Pour les modèles fonctionnant sur une plage de données modifiables, elle définit également l’indicateur permettant de modifier l’élément (ItemIsEditable).
Les modèles qui renvoient une liste non vide de mimeTypes() activent également le drapeau Qt::ItemIsDragEnabled et, sauf s’ils sont en lecture seule, le drapeau Qt::ItemIsDropEnabled.
Les modèles plats activent le drapeau « Qt::ItemNeverHasChildren » pour tous les éléments, tandis que les modèles hiérarchiques l’activent pour tous les éléments des colonnes situées au-dessus de la 0e.
Pour personnaliser les indicateurs en fonction de vos propres types de données, fournissez une spécialisation de RowOptions et/ou ItemAccess pour vos types de lignes ou d'éléments, et implémentez une fonction membre statique flags() :
template <>
struct QRangeModel::ItemAccess<ColorEntry>
{
static Qt::ItemFlags flags(const ColorEntry &entry)
{
return entry.flags();
}
};Voir également Qt::ItemFlags, RowOptions et ItemAccess.
[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 correspondant à l'role et à l'section données dans l'en-tête, avec l'orientation spécifiée.
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 l’ 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 alors le nom du type à l’ section. Pour les lignes de type gadget ou QObject, cette fonction renvoie le nom de la propriété à l’index de section.
Pour personnaliser les données de l’en-tête horizontal de votre propre plage, fournissez une spécialisation de ` RowOptions ` pour vos types de lignes et implémentez une fonction membre de classe ` headerData()` :
template <>
struct QRangeModel::RowOptions<ColorEntry>
{
static QVariant headerData(int section, int role)
{
switch (section) {
// ...
}
return {};
}
};Pour l'en-tête verticale, cette fonction renvoie toujours le résultat de l'implémentation par défaut dans ` QAbstractItemModel`.
Voir également Qt::ItemDataRole, setHeaderData(), QHeaderView et RowOptions.
[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 du modèle situé à row et column dans parent.
Le passage d’un parent valide produit un index invalide pour les modèles fonctionnant sur des plages de listes et de tableaux.
Voir également 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 situé à l'adresse column dans toutes les lignes de la plage définie par 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 dont le type de ligne a une taille statique (comme un tuple, un tableau ou une structure), cette implémentation ne fait rien et renvoie immédiatement « false ». C’est toujours le cas pour les modèles arborescents.
[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 l'row e spécifié dans la plage située à l'adresse parent. Renvoie true en cas de succès ; sinon, renvoie false.
Remarque : la plage doit être de taille 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 (telle qu’un tableau), cette implémentation ne fait rien et renvoie immédiatement false.
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 table contenant les valeurs de tous les rôles prédéfinis dans le modèle pour l’élément situé à l’ index donné.
Si le type d’élément correspondant à cet index est un conteneur associatif qui effectue une mise en correspondance entre int, Qt::ItemDataRole ou QString et un QVariant, alors 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 à une ` role name ` sont renvoyées.
Si l’élément n’est ni un conteneur associatif, ni un gadget, ni une sous-classe de ` QObject `, cette méthode appelle alors l’implémentation de la classe de base.
Voir également ` 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.
Renvoie une liste d’index correspondant aux éléments de la colonne de ` start ` pour lesquels les données stockées sous ` role ` correspondent à ` value`, en utilisant les critères de correspondance définis par ` flags`. Utilisez ` hits = -1` pour trouver tous les éléments correspondants.
Remarque : cette implémentation lit les données directement à partir de la plage C++ sous-jacente et ne passe pas par les surcharges de la méthode ` data()`.
[override virtual] QMimeData *QRangeModel::mimeData(const QModelIndexList &indexes) const
Réimplémente : QAbstractItemModel::mimeData(const QModelIndexList &indexes) const.
Si une personnalisation de ` ItemAccess ` est disponible pour le type d’élément stocké dans la plage, et si cette personnalisation implémente une fonction membre de classe ` mimeData()` appropriée, alors cette implémentation appelle cette fonction et renvoie le résultat.
template <>
struct QRangeModel::ItemAccess<ColorEntry>
{
static QMimeData *mimeData(const auto &range)
{
QByteArray data;
QTextStream stream(&data, QIODevice::WriteOnly);
for (const auto &[item, index] : range)
stream << item.colorName() << Qt::endl;
QMimeData *result = new QMimeData;
result->setData(mimeTypes().first(), data);
// Qt handles encoding into the default mime type
return result;
}
};Sinon, si une personnalisation de ` RowOptions ` est disponible pour le type de ligne de la plage et qu’elle comporte une fonction membre de classe ` mimeData()` appropriée, cette implémentation renvoie alors le résultat de l’appel à cette fonction.
template <>
struct QRangeModel::RowOptions<ColorEntry>
{
template <typename Items>
static QMimeData *mimeData(const Items &items)
{
if (items.isEmpty())
return nullptr;
QByteArray data;
QXmlStreamWriter stream(&data);
stream.writeStartElement("ul");
for (const auto &[item, index] : items)
stream.writeTextElement("li", item.colorName());
stream.writeEndElement();
QMimeData *mimeData = new QMimeData;
mimeData->setData(mimeTypes().first(), data);
return mimeData;
}
};Si aucune de ces deux personnalisations n’est disponible, cette implémentation renvoie alors le résultat de l’implémentation par défaut de ` QAbstractItemModel `.
Voir également Drag'n'drop handling, RowOptions::mimeData(), ItemAccess::mimeData(), canDropMimeData(), dropMimeData() et mimeTypes().
[override virtual] QStringList QRangeModel::mimeTypes() const
Réimplémente : QAbstractItemModel::mimeTypes() const.
Si une personnalisation de ` ItemAccess ` est disponible pour le type d’élément stocké dans la plage, et si cette personnalisation implémente une fonction membre de classe ` mimeTypes()` appropriée, alors cette implémentation appelle cette fonction et renvoie le résultat.
template <>
struct QRangeModel::ItemAccess<ColorEntry>
{
static QStringList mimeTypes()
{
return {
u"text/plain"_s,
u"application/x-qabstractitemmodeldatalist"_s
};
}
};Sinon, si une personnalisation de ` RowOptions ` est disponible pour le type de ligne de la plage et qu’elle comporte une fonction membre de classe ` mimeTypes()` appropriée, cette implémentation renvoie le résultat de l’appel à cette fonction.
template <>
struct QRangeModel::RowOptions<ColorEntry>
{
static QStringList mimeTypes()
{
return {
u"text/html"_s
};
}
};Si aucune de ces deux personnalisations n’est disponible, cette implémentation renvoie alors le résultat de l’implémentation par défaut de ` QAbstractItemModel `.
Voir également Drag'n'drop handling, RowOptions::mimeTypes(), ItemAccess::mimeTypes(), canDropMimeData(), dropMimeData() et mimeData().
[override virtual] bool QRangeModel::moveColumns(const QModelIndex &sourceParent, int sourceColumn, int count, const QModelIndex &destinationParent, int destinationColumn)
Réimplémentation de : QAbstractItemModel::moveColumns(const QModelIndex &sourceParent, int sourceColumn, int count, const QModelIndex &destinationParent, int destinationChild).
Déplace les colonnes count commençant par l'sourceColumn on donnée 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 l'sourceRow donné 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 situé à l'index child.
Cette fonction produit toujours un index non valide pour les modèles fonctionnant sur des plages de listes et de tableaux. Pour les modèles fonctionnant sur une arborescence, cette fonction renvoie l’index de l’élément de ligne renvoyé par l’implémentation de la fonction parent() du protocole de traversée d’arborescence.
Voir également 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 les colonnes de type « count » de l’élément situé à l’adresse column et suivantes dans toutes les lignes de la plage située à l’adresse parent. Renvoie « true » en cas de succès, sinon renvoie « false ».
Remarque : un type de ligne à taille dynamique doit fournir une fonction membre « erase(const_iterator, size_t) ».
Pour les modèles fonctionnant sur une plage en lecture seule, ou sur une plage avec un type de ligne à taille statique (tel qu’un tuple, un tableau ou une structure), cette implémentation ne fait rien et renvoie immédiatement false. C’est toujours le cas pour les modèles arborescents.
[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 les lignes de type ` count ` de la plage située à l'adresse ` parent`, en commençant par l'row` indiquée. Renvoie ` true ` en cas de succès, sinon renvoie ` false`.
Remarque : la plage doit être de taille dynamique et fournir une fonction membre erase(const_iterator, size_t).
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 immédiatement ` false `.
[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 possiblede redéfinir cette fonction dans une sous-classe de ` QRangeModel `, mais cela peut perturber le comportement de la propriété.
Remarque : fonctionde lecture pour la propriété `roleNames`.
Voir également setRoleNames().
[override virtual] int QRangeModel::rowCount(const QModelIndex &parent = {}) const
Réimplémente : QAbstractItemModel::rowCount(const QModelIndex &parent) const.
Renvoie le nombre de lignes situées sous l’index « parent » donné. Il s’agit du nombre d’éléments dans la plage racine pour un index « parent » non valide.
Si l’index ` parent ` est valide, cette fonction renvoie toujours 0 pour les modèles fonctionnant sur des plages de listes et de tableaux. Pour les arbres, elle renvoie la taille de la plage renvoyée par l’implémentation de la méthode `childRows()` du protocole de traversée d’arbre.
Voir également 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 l'role pour l'élément situé à l'adresse index sur data.
Si le type de l'élément pour cet index est un conteneur associatif qui établit une correspondance entre int, Qt::ItemDataRole ou QString et un QVariant, alors data est stocké dans ce conteneur pour la clé spécifiée par role.
Si l’élément est un gadget ou un 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 contenait une valeur pouvant être convertie au type requis ; sinon, elle renvoie false.
Sinon, cette implémentation attribue la valeur de data à l’élément situé à l’adresse index dans la plage pour Qt::DisplayRole et Qt::EditRole, et renvoie true. Pour les autres rôles, l’implémentation renvoie false.
Pour les modèles opérant sur une plage en lecture seule, ou sur une colonne en lecture seule d’un type de ligne implémentant the C++ tuple protocol, cette implémentation renvoie immédiatement false.
Voir également 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 cet ` index ` est un conteneur associatif qui établit une correspondance entre soit ` int `, soit ` Qt::ItemDataRole ` et ` QVariant`, alors les entrées de ` data ` sont stockées dans ce conteneur. Si le conteneur associatif établit une correspondance entre ` QString ` et ` QVariant`, alors 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 correspondant à une entrée de role name sont alors définies sur la valeur correspondante dans data.
Les rôles pour lesquels il n’existe aucune entrée dans ` data ` ne sont pas modifiés.
Pour les types d’éléments pouvant être copiés, cette implémentation est transactionnelle et renvoie « true » si toutes les entrées de data ont pu être enregistrées. Si une entrée n’a pas pu être mise à jour, le conteneur d’origine n’est alors pas modifié du tout et la fonction renvoie « false ».
Si l’élément n’est pas un conteneur associatif, un gadget ou une sous-classe de ` QObject `, cette 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 situé à l'adresse row et column pour l'élément situé à l'adresse index, ou un QModelIndex invalide s'il n'y a pas de frère à cet emplacement.
Cette implémentation est nettement plus rapide que de passer par la méthode parent() de index.
Voir également index(), QModelIndex::row() et QModelIndex::column().
[override virtual] void QRangeModel::sort(int column, Qt::SortOrder order = Qt::AscendingOrder)
Réimplémentation de : QAbstractItemModel::sort(int column, Qt::SortOrder order).
Trie la plage sous-jacente selon l’ order donné, en fonction des données de l’ sortRole (Qt::DisplayRole par défaut) des éléments de column.
Remarque : cette implémentation utilise une fonction membre ` sort(Compare comp) ` de la plage C++ si celle-ci est disponible (comme dans ` std::list`), ou bien ` std::stable_sort() ` si la plage fournit des itérateurs à accès aléatoire. Si aucune des deux n’est disponible, l’implémentation ne fait rien et retourne immédiatement.
Remarque : l'accès à l'élément ne déclenche pas la lecture des données via des redéfinitions de data().
Voir également sortRole et QSortFilterProxyModel.
[override virtual] QSize QRangeModel::span(const QModelIndex &index) const
Réimplémente : QAbstractItemModel::span(const QModelIndex &index) 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.