(1)给出本 QModelRoleData 类的源码 :
/*
The QModelRoleData class holds a role and the data associated to that role.
QModelRoleData对象存储一个项目角色的任意整数),以及与该角色关联的数据。
(这是来自Qt::ltemDataRole枚举的值,或者是一个自定义角色.
QModelRoleData objects store an item role
(which is a value from the Qt::ItemDataRole enumeration,
or an arbitrary integer for a custom role)
as well as the data associated with that role.
QModelRoleData 对象通常由视图或代理创建,并设置他们要为其获取数据的角色。
然后将该对象传递给模型(参见QAbstractltemModel::multiData()).
这些模型填充与存储的角色相对应的数据。最后,视图可视化从模型中检索到的数据。
A QModelRoleData object is typically created by views or delegates,
setting which role they want to fetch the data for.
The object is then passed to models (see QAbstractItemModel::multiData()),
which populate the data corresponding to the role stored.
Finally, the view visualizes the data retrieved from the model.
*/
class QModelRoleData
{
int m_role;
QVariant m_data;
public:
//Constructs a QModelRoleData object for the given role.
explicit QModelRoleData(int role) noexcept : m_role(role) {} //有参构造函数
//Returns the role held by this object.
constexpr int role() const noexcept { return m_role; }
constexpr QVariant & data() noexcept { return m_data; }
//Returns the data held by this object as a modifiable reference.
constexpr const QVariant & data() const noexcept { return m_data; }
//Returns the data held by this object.
template <typename T>
constexpr
void setData(T && value)
noexcept(noexcept(m_data.setValue(std::forward<T>(value))))
{ m_data.setValue(std::forward<T>(value)); }
//Sets the data held by this object to value.
//value must be of a datatype which can be stored in a QVariant.
//Clears the data held by this object.
//Note that the role is unchanged; only the data is cleared.
void clearData() noexcept { m_data.clear(); }
}; //完结 class QModelRoleData
Q_DECLARE_TYPEINFO(QModelRoleData, Q_RELOCATABLE_TYPE); //本类型的存储特征:可重定位。
(2)给出 QModelRoleDataSpan 的源码 :
/*
The QModelRoleDataSpan class provides a span over QModelRoleData objects.
QModelRoleDataSpan 是对数组中 QModelRoleData 对象的抽象。
A QModelRoleDataSpan is used as an abstraction over an array of QModelRoleData objects.
Like a view, QModelRoleDataSpan provides a small object (pointer and size) that
can be passed to functions that need to examine the contents of the array.
A QModelRoleDataSpan can be constructed from any array-like sequence (plain arrays,
QVector, std::vector, QVarLengthArray, and so on).
Moreover, it does not own the sequence, which must therefore be kept alive longer than
any QModelRoleDataSpan objects referencing it.
就像视图一样,QModelRoleDataSpan提供一个小对象(指针和大小),可以传递给需要检查数组内容的函数。
QModelRoleDataSpan 可以从任何类似数组的序列构建(如普通数组、QVector、std:vector、QVarLengthArray.
等此外,它不拥有该序列,因此必须确保该序列的生命周期长于任何引用它的QModelRoleDataSpan对象。
与视图不同,QModelRoleDataSpan 是一个跨度,因此允许对底层元素进行修改。
Unlike a view, QModelRoleDataSpan is a span,
so it allows for modifications to the underlying elements.
QModelRoleDataSpan的主要用途是使模型能够在一次调用中返回对应不同角色的数据。
QModelRoleDataSpan's main use case is making it possible for a model to return the
data corresponding to different roles in one call.
为了从模型中提取一个元素,视图(通过其委托)通常会根据需要多次调用`data()方法,以获取同一索引处的多个角色!
In order to draw one element from a model,
a view (through its delegates) will generally request multiple roles for the
same index by calling data() as many times as needed:
QVariant text = model->data(index, Qt::DisplayRole);
QVariant decoration = model->data(index, Qt::DecorationRole);
QVariant checkState = model->data(index, Qt::CheckStateRole);
// etc.
QModelRoleDataSpan允许视图使用一个函数调用请求相同的数据。
实现这一点的方法是,让视图准备一个合适的 QModelRoleData 对象数组,每个对象都初始化为应被获取的角色。
然后将该数组封装在 QModelRoleDataSpan 对象中,接着传递给模型的multiData()函数。
QModelRoleDataSpan allows a view to request the same data using just one function call.
This is achieved by having the view prepare a suitable array of QModelRoleData objects,
each initialized with the role that should be fetched.
The array is then wrapped in a QModelRoleDataSpan object,
which is then passed to a model's multiData() function.
使用 QModelRoleDataSpan 的举例如下:
std::array<QModelRoleData, 3> roleData = { {
QModelRoleData(Qt::DisplayRole ),
QModelRoleData(Qt::DecorationRole),
QModelRoleData(Qt::CheckStateRole)
} };
// Usually, this is not necessary: A QModelRoleDataSpan
// will be built automatically for you when passing an array-like
// container to multiData().
QModelRoleDataSpan span(roleData);
model->multiData(index, span);
// Use roleData[0].data(), roleData[1].data(), etc.
建议将 QModelRoleData 对象的数组(可能还包括相应的跨度)存储起来,并在后续对模型的调用中重复使用。
这样可减少与创建和返回 QVariant 对象相关的内存分配。
Views are encouraged to store the array of QModelRoleData objects
(and, possibly, the corresponding span) and re-use it in subsequent calls to the model.
This allows to reduce the memory allocations related with creating and
returning QVariant objects.
最后,给定一个QModelRoleDataSpan对象,模型的职责是填充与span中每个角色对应的数据。
具体如何实现取决于具体的模型类。
以下是一个可能的实现概述,它遍历整个span,并对每个元素调用setData()函数:
Finally, given a QModelRoleDataSpan object,
the model's responsibility is to fill in the data corresponding to each role in the span.
How this is done depends on the concrete model class.
Here's a sketch of a possible implementation that iterates over the span and
uses setData() on each element:
void MyModel::multiData(const QModelIndex & index,
QModelRoleDataSpan roleDataSpan) const
{
for (QModelRoleData & roleData : roleDataSpan)
{
int role = roleData.role();
// ... obtain the data for index and role ...
roleData.setData(result);
}
}
*/
class QModelRoleDataSpan //看着好像是在堆区存储了 len 个 QModelRoleData 类型的数据
{ //看着是封装于构成了 m_modelRoleData 数组。
QModelRoleData * m_modelRoleData = nullptr;
qsizetype m_len = 0;
template <typename T>
using if_compatible_container = std::enable_if_t<
QtPrivate::IsContainerCompatibleWithModelRoleDataSpan<T>::value, bool>;
public:
//Constructs an empty QModelRoleDataSpan.
//Its data() will be set to nullptr, and its length to zero.
constexpr QModelRoleDataSpan() noexcept {} //无参构造函数
//Constructs an QModelRoleDataSpan spanning over modelRoleData,
// seen as a 1-element array.
constexpr QModelRoleDataSpan(QModelRoleData & modelRoleData) noexcept //有参构造函数
: m_modelRoleData(&modelRoleData), m_len(1) {}
//Constructs an QModelRoleDataSpan spanning over the array,
// beginning at modelRoleData and with length len.
//Note: The array must be kept alive as long as this object has not been destructed.
constexpr QModelRoleDataSpan(QModelRoleData * modelRoleData, qsizetype len)
: m_modelRoleData(modelRoleData), m_len(len) {} //有参构造函数
template <typename Container, if_compatible_container<Container> = true>//有参构造函数
constexpr QModelRoleDataSpan(Container & c)
noexcept(noexcept(std::data(c)) && noexcept(std::size(c)))
: m_modelRoleData(std::data(c)), m_len(qsizetype(std::size(c))) {}
//Returns the length of the span represented by this object.
constexpr qsizetype size () const noexcept { return m_len; }
constexpr qsizetype length() const noexcept { return m_len; }
//Returns a pointer to the beginning of the span represented by this object.
constexpr QModelRoleData * data () const noexcept { return m_modelRoleData; }
constexpr QModelRoleData * begin() const noexcept { return m_modelRoleData; }
constexpr QModelRoleData * end () const noexcept { return m_modelRoleData + m_len; }
//Returns a pointer to the imaginary element one past the
// end of the span represented by this object.
//指向 QModelRoleData 数组里的最后一个元素的后面的虚拟元素的地址。
constexpr QModelRoleData & operator[](qsizetype index) const
{ return m_modelRoleData[index]; }
//返回 QModelRoleData 数组里第一个对应形参角色的数据
constexpr QVariant * dataForRole(int role) const
{
auto result = begin();
const auto e = end ();
for (; result != e; ++result)
if (result->role() == role) break;
return Q_ASSERT(result != end()), &result->data();
}
//Returns the data associated with the
// first QModelRoleData in the span that has its role equal to role.
//If such a QModelRoleData object does not exist, the behavior is undefined.
//Note: Avoid calling this function from the model's side,
//as a model cannot possibly know in advance which roles are in a
// given QModelRoleDataSpan.
//This function is instead suitable for views and delegates,
// which have control over the roles in the span.
}; //完结 class QModelRoleDataSpan
Q_DECLARE_TYPEINFO(QModelRoleDataSpan, Q_RELOCATABLE_TYPE); //指出本类的存储方式
(3)应用举例如下 :
QVariant text = model->data(index, Qt::DisplayRole);
QVariant decoration = model->data(index, Qt::DecorationRole);
QVariant checkState = model->data(index, Qt::CheckStateRole);
// etc.
//********************以及************************************
std::array<QModelRoleData, 3> roleData = { {
QModelRoleData(Qt::DisplayRole),
QModelRoleData(Qt::DecorationRole),
QModelRoleData(Qt::CheckStateRole)
} };
// Usually, this is not necessary: A QModelRoleDataSpan
// will be built automatically for you when passing an array-like
// container to multiData().
QModelRoleDataSpan span(roleData);
model->multiData(index, span);
// Use roleData[0].data(), roleData[1].data(), etc.
(4)给出本类的继承关系图 :

(5)
谢谢

被折叠的 条评论
为什么被折叠?



