(1)本选择模型类存在的意义,最重要的方面,感觉是可以被同一模型的多个视图共享 :
++
(2)开始本类的学习,因为本类的属性,没有官方注释,就不单独测试了。给出构造函数 :
(3)还是简要给出本类的属性 :
++
(4)
++测试结果 ;
(5)
++
(6)以下,接着学习本类的公共成员函数 :
++
++测试 ;
++
++ 测试一下 :
++本类的公共成员函数结束。
(7)本类的保护权限的成员函数,很少,只有这两个 :
(8)接着学习本类的槽函数 , 先介绍一个选择枚举量 :
++第一个槽函数 :
++
++
++至此,槽函数学习完毕。测试少了一点,以后用到的时候再说算了。
(9)接着学习本类的信号函数 :
++
++测试一下 :
++ 至此,本选择模型类学习与阅读完毕。
(10)本类定义于头文件 qitemselectionmodel . h :
#ifndef QITEMSELECTIONMODEL_H
#define QITEMSELECTIONMODEL_H
#include <QtCore/qglobal.h>
#include <QtCore/qabstractitemmodel.h>
#include <QtCore/qlist.h>
#include <QtCore/qset.h>
QT_REQUIRE_CONFIG(itemmodel);
QT_BEGIN_NAMESPACE
/*
The QItemSelectionRange class manages information about a
range of selected items in a model.
QltemSelectionRange 类管理模型中选定项目范围的信息。
Detailed Description :
QltemSelectionRange`包含关于模型中选定项范围的信息。
项范围是模型项的连续数组,延伸以覆盖具有共同父项的多个相邻行和列;
这可以可视化为一个表格中的二维单元块。
一个选择范围具有`top()、right()'和一个`parent()、left()、bottom().
QItemSelectionRange类是模型/视图类之一,是Qt模型/视图框架的一部分。
通过使用`indexes()、函数,可以获取选定的范围中所包含的模型项。
使用QItemSelectionModel::selectedIndexes()、可获取视图中所有选中的项的列表。
您可以通过使用“ contains() ”函数来确定给定的模型项是否位于特定范围内。
还可以使用重载的等于和不等于运算符来比较范围,而“ intersects() 函数则允许您确定两个范围是否重叠。
*/
class Q_CORE_EXPORT QItemSelectionRange
{ //本类描述的是这样的选择项:这些被选择的条目都是连续的。
private: //tl : top left , br : bottom right 的含义
QPersistentModelIndex tl, br; //使用了两个持久索引作为自己的数据成员
public:
QItemSelectionRange() = default; //默认构造函数
QItemSelectionRange(const QModelIndex & topL, const QModelIndex & bottomR)//有参构造函数
: tl(topL), br(bottomR) {}
explicit
QItemSelectionRange(const QModelIndex & index) : tl(index), br(tl) {} //有参构造函数
inline bool operator==(const QItemSelectionRange & other) const //比较运算符函数
{ return (tl == other.tl && br == other.br); }
inline bool operator!=(const QItemSelectionRange & other) const
{ return !operator==(other); }
void swap(QItemSelectionRange & other) noexcept
{
tl.swap(other.tl);
br.swap(other.br);
}
inline const QPersistentModelIndex & topLeft() const { return tl; }
inline const QPersistentModelIndex & bottomRight() const { return br; }
inline int top() const { return tl.row (); }
inline int left() const { return tl.column(); }
inline int bottom() const { return br.row (); }
inline int right () const { return br.column(); }
inline int width() const { return br.column() - tl.column() + 1; }
inline int height() const { return br.row() - tl.row() + 1; }
//Returns true if the selection range is valid; otherwise returns false.
inline
bool isValid() const //若本选择范围有效,则返回 true。
{
return (
tl .isValid()
&& br.isValid()
&& tl.parent() == br.parent()
&& top () <= bottom()
&& left() <= right());
}
bool isEmpty() const;
//如果选择范围包含没有项目或仅包含禁用或标记为不可选的项目,则返回true。
//Returns the model that the items in the selection range belong to.
inline const QAbstractItemModel * model () const { return tl.model (); }
inline QModelIndex parent () const { return tl.parent(); }
//Returns the parent model item index of the items in the selection range.
//返回这些被选条目的父节点的索引。
QModelIndexList indexes() const;
//Returns the list of model index items stored in the selection.
//判断本选择范围里是否包含形参 index指向的条目。
inline bool contains( const QModelIndex & index) const
{
return (
parent() == index.parent()
&& tl.row() <= index.row() && tl.column() <= index.column()
&& br.row() >= index.row() && br.column() >= index.column()
);
}
//判断节点 parentIndex下属的子表里元素 [row, column]是否在本选择范围内。
inline bool contains(int row, int column, const QModelIndex & parentIndex) const
{
return (
parent() == parentIndex
&& tl.row() <= row && tl.column() <= column
&& br.row() >= row && br.column() >= column
);
}
//如果此选择范围与给定的 other范围相交(重叠),则返回true;否则返回false。
bool intersects (const QItemSelectionRange & other) const;
QItemSelectionRange intersected(const QItemSelectionRange & other) const;
//返回一个新的选择范围,仅包含在选定范围和 other选定范围内都找到的项目。
}; //完结 class Q_CORE_EXPORT ItemSelectionRange
Q_DECLARE_TYPEINFO(QItemSelectionRange, Q_RELOCATABLE_TYPE);
Q_CORE_EXPORT QDebug operator<<(QDebug, const QItemSelectionRange &);
//此 << 运算符函数说明本类支持调试打印输出。
/*
The QItemSelection class manages information about selected items in a model.
Detailed Description :
QItemSelection`描述了模型中被用户选中的项。
`QItemSelection`大体上是一个选择范围列表,参见QItemSelectionRange~。
它提供了创建和操作选择以及从模型中选择一系列项的功能。
QItemSelection类是Model/iew类之一,并且是Qt模型/视图框架的一部分。
可以构建和初始化一个项选择,以包含来自现有模型的一组项。
以下示例构建了一个选择,其包含从给定的模型中选取的一组项,起始点为左上角,结束点为右下角。
QItemSelection * selection = new QItemSelection(topLeft, bottomRight);
可以构建一个空的项目选择,然后在需要时进行填充。
因此,如果在构建项目选择时模型不可用,我们可以将上述代码重写为以下形式:
QItemSelection * selection = new QItemSelection();
...
selection->select(topLeft, bottomRight);
QItemSelection 通过处理选择范围而非为选择中的每个项目记录模型项索引,来节省内存并避免不必要的操作。
通常,该类的一个实例将包含一组不重叠的选择范围。
使用merge()函数可以将一个项选择合并到另一个选择中,而不会产生重叠范围。
使用split()函数可以根据另一个选择范围将一个选择范围分割成更小的范围。
*/
// We export each out-of-line method individually to prevent MSVC from
// exporting the whole QList class.
class QItemSelection : public QList<QItemSelectionRange>
{
public:
using QList<QItemSelectionRange>::QList; //这是列表 QList的构造函数
//Constructs an item selection that extends from the top-left model item,
// specified by the topLeft index,
// to the bottom-right item, specified by bottomRight.
Q_CORE_EXPORT
QItemSelection(const QModelIndex & topLeft, const QModelIndex & bottomRight);//构造函数
Q_CORE_EXPORT
void select (const QModelIndex & topLeft, const QModelIndex & bottomRight);
//Adds the items in the range that extends from the top-left model item,
// specified by the topLeft index,
// to the bottom-right item, specified by bottomRight to the list.
//Note: topLeft and bottomRight must have the same parent.
// reusing QList::swap() here is OK!
//Returns true if the selection contains the given index; otherwise returns false.
Q_CORE_EXPORT bool contains(const QModelIndex & index) const; //是否包含形参索引
Q_CORE_EXPORT QModelIndexList indexes() const; //返回所有的本选择条目的索引。
//Returns a list of model indexes that correspond to the selected items.
//Merges the other selection with this QItemSelection using the command given.
//This method guarantees that no ranges are overlapping.
//Note that only QItemSelectionModel::Select,
// QItemSelectionModel::Deselect, and QItemSelectionModel::Toggle are supported.
Q_CORE_EXPORT void merge(const QItemSelection & other,
QItemSelectionModel::SelectionFlags command);
/*
enum QItemSelectionModel::SelectionFlag {
NoUpdate = 0x0000,
Clear = 0x0001,
Select = 0x0002,
Deselect = 0x0004,
Toggle = 0x0008,
Current = 0x0010,
Rows = 0x0020,
Columns = 0x0040,
SelectCurrent = Select | Current,
ToggleCurrent = Toggle | Current,
ClearAndSelect = Clear | Select
};
*/
//把选择范围里 range里的也属于选择范围 other的条目全部删除,得到的新条目范围对象存入形参 result中。
Q_CORE_EXPORT //注意,这是个静态成员函数
static void split(const QItemSelectionRange & range,
const QItemSelectionRange & other,
QItemSelection * result);
//Splits the selection range using the selection other range.
//Removes all items in other from range and puts the result in result.
//This can be compared with the semantics of the subtract operation of a set.
//这可以与集合的减法操作的语义进行比较。
}; //class QItemSelection : QList<QItemSelectionRange>
Q_DECLARE_SHARED(QItemSelection)
class QItemSelection;
class QItemSelectionModelPrivate;
/*
The QItemSelectionModel class keeps track of a view's selected items.
Detailed Description:
QltemSelectionModel`能够跟踪视图中或同一模型上的多个视图中已选中的项,同时还能跟踪视图中当前选中的项。
QltemSelectionModel类是模型/视图类之一,是Qt的模型/视图框架的一部分。
所选项目使用范围进行存储。
每当你想修改所选项目时,请使用select()并提供QItemSelection,
或者QModeIndex和QItemSelectionModel::SelectionFlag.
QItemSelectionModel`采用两层方法来处理选择管理,既处理已提交的选择项,也处理当前选择范围内的项目。
当前选择项属于当前交互式选择范围(例如使用橡皮筋 rubber-band 选择或键盘Shift选择)。
要更新当前选中的项,请使用`QItemSelectionModel:Current`与其他任何`SelectionFlags`的按位或操作。
如果您省略了`QItemSelectionMode: current'命令,
则会创建一个新的当前选择,并将之前的当前选择添加到整个选择中。
所有函数都在两个层上操作,例如,`selectedltems()、将同时返回两个层的项。
*/
class Q_CORE_EXPORT QItemSelectionModel : public QObject
{
Q_OBJECT
//官方文档并没有给出本类里的属性的注释讲解。
Q_PROPERTY(QAbstractItemModel * model
READ model WRITE setModel
NOTIFY modelChanged
BINDABLE bindableModel)
Q_PROPERTY(bool hasSelection
READ hasSelection
NOTIFY selectionChanged
STORED false
DESIGNABLE false)
Q_PROPERTY(QModelIndex currentIndex
READ currentIndex
NOTIFY currentChanged
STORED false
DESIGNABLE false)
Q_PROPERTY(QItemSelection selection
READ selection
NOTIFY selectionChanged
STORED false
DESIGNABLE false)
Q_PROPERTY(QModelIndexList selectedIndexes
READ selectedIndexes
NOTIFY selectionChanged
STORED false
DESIGNABLE false)
Q_DECLARE_PRIVATE(QItemSelectionModel)
private:
Q_DISABLE_COPY(QItemSelectionModel)
Q_PRIVATE_SLOT(d_func(),
void _q_columnsAboutToBeInserted(const QModelIndex &, int, int))
Q_PRIVATE_SLOT(d_func(),
void _q_columnsAboutToBeRemoved (const QModelIndex &, int, int))
Q_PRIVATE_SLOT(d_func(),
void _q_rowsAboutToBeInserted(const QModelIndex &, int, int))
Q_PRIVATE_SLOT(d_func(),
void _q_rowsAboutToBeRemoved (const QModelIndex &, int, int))
Q_PRIVATE_SLOT(d_func(), void _q_layoutAboutToBeChanged(
const QList<QPersistentModelIndex> & parents = QList<QPersistentModelIndex>(),
QAbstractItemModel::LayoutChangeHint hint = QAbstractItemModel::NoHint))
Q_PRIVATE_SLOT(d_func(), void _q_layoutChanged(
const QList<QPersistentModelIndex> & parents = QList<QPersistentModelIndex>(),
QAbstractItemModel::LayoutChangeHint hint = QAbstractItemModel::NoHint))
Q_PRIVATE_SLOT(d_func(), void _q_modelDestroyed())
public:
//Constructs a selection model that operates on the specified item model.
//创造一个选择模型,以管理形参 model模型中的数据。
explicit QItemSelectionModel(QAbstractItemModel * model = nullptr);
//应该多用带 parent的版本,避免内存泄露。可赋值为 this。由主窗体完成本选择模型的析构。
explicit QItemSelectionModel(QAbstractItemModel * model, QObject * parent);
//Constructs a selection model that operates on the specified item model with parent.
//这里的形参 parent,应该是使用本选择模型的视图对象。选择模型是可被多视图共享的。
virtual ~QItemSelectionModel();
/*
class QAbstractItemView : public QAbstractScrollArea
{
//Returns the current selection model.
QItemSelectionModel * selectionModel() const; //返回视图用的选择模型
virtual void setSelectionModel(QItemSelectionModel * selectionModel);
//Sets the current selection model to the given selectionModel.
//请注意,如果在调用此函数之后调用setModel(),则给定的选择模型将被视图创建的一个模型替换。
//注:应用程序有责任在不再需要时删除旧的选择模型,即,如果其他视图不再使用它.
//当其父对象被删除时,这将会自动发生。
//然而,如果它没有父对象,或者如果父对象是一个生命周期较长的对象,
//那么调用其`deleteLater()、函数以明确删除它可能更为合适。
};
*/
// Q_PROPERTY(QAbstractItemModel * model
// READ model WRITE setModel
// NOTIFY modelChanged
// BINDABLE bindableModel)
QAbstractItemModel * model();
const QAbstractItemModel * model() const;
void setModel(QAbstractItemModel * model);
Q_SIGNALS:
void modelChanged(QAbstractItemModel * model);
public:
QBindable<QAbstractItemModel *> bindableModel();
// Q_PROPERTY(bool hasSelection
// READ hasSelection
// NOTIFY selectionChanged
// STORED false //对比一下,本属性可支持范围选择
// DESIGNABLE false) //关于本属性的使用,以后还需再次测试。
bool hasSelection() const;
//如果选择模型包含任何选定的项目,则返回true,否则返回false。
Q_SIGNALS: //测试发现,信号函数的形参 2 在本版本,不可以使用。
void selectionChanged(const QItemSelection & selected,
const QItemSelection & deselected);
public:
// Q_PROPERTY(QModelIndex currentIndex
// READ currentIndex
// NOTIFY currentChanged
// STORED false //对比一下,本属性只支持单选。
// DESIGNABLE false)
QModelIndex currentIndex() const;
Q_SIGNALS: //返回当前项目的模型项索引,如果没有当前项目则返回无效索引。
void currentChanged(const QModelIndex & current,
const QModelIndex & previous);
public:
// Q_PROPERTY(QItemSelection selection
// READ selection
// NOTIFY selectionChanged
// STORED false
// DESIGNABLE false)
const QItemSelection selection() const;
Q_SIGNALS: //这个信号函数是重复的。返回存储在选择模型中的选择范围。
void selectionChanged(const QItemSelection & selected,
const QItemSelection & deselected);
public:
// Q_PROPERTY(QModelIndexList selectedIndexes
// READ selectedIndexes
// NOTIFY selectionChanged
// STORED false
// DESIGNABLE false)
QModelIndexList selectedIndexes() const;
Q_SIGNALS: //这个信号函数是重复的。返回存储在选择模型中的选择范围。
void selectionChanged(const QItemSelection & selected,
const QItemSelection & deselected);
public:
//Returns true if the given model item index is selected.
Q_INVOKABLE bool isSelected(const QModelIndex & index) const;
//Returns true if all items are selected in the row with the given parent.
//请注意,此函数通常比在同一行的所有项目上调用isSelected()更快,并且不可选择的项目将被忽略。
Q_INVOKABLE bool isRowSelected(int row, //若本行的所有可选条目被选中了,则返回真。
const QModelIndex & parent = QModelIndex()) const;
Q_INVOKABLE bool isColumnSelected(int column, //若某列里的元素全被选中了,则返回真。
const QModelIndex & parent = QModelIndex()) const;
//Returns true if all items are selected in the column with the given parent.
//只要某行里有元素被选中,本行就返回 true。
//Returns true if there are any items selected in the row with the given parent.
Q_INVOKABLE bool rowIntersectsSelection(int row , //Intersect 交叉;相交
const QModelIndex & parent = QModelIndex()) const;
Q_INVOKABLE bool columnIntersectsSelection(int column,
const QModelIndex & parent = QModelIndex()) const;
//只要某列里有元素被选中,本行就返回 true。
//Returns the indexes in the given column for the rows where all columns are selected.
//对于全选的行们,只返回行中的第 column列的元素的索引。
Q_INVOKABLE //返回给定列中所有列都被选择的行在该列中的索引。
QModelIndexList selectedRows (int column = 0) const;
Q_INVOKABLE
QModelIndexList selectedColumns(int row = 0) const;
//Returns the indexes in the given row for columns where all rows are selected.
//对于全选的列们,只返回列中第 row行元素的索引。
protected:
QItemSelectionModel(QItemSelectionModelPrivate & dd, QAbstractItemModel * model);
void emitSelectionChanged(const QItemSelection & newSelection,
const QItemSelection & oldSelection);
//Compares the two selections newSelection and oldSelection and
// emits selectionChanged() with the deselected and selected items.
public Q_SLOTS:
//This enum describes the way the selection model will be updated.
enum SelectionFlag {
NoUpdate = 0x0000,//No selection will be made.
Clear = 0x0001,//The complete selection will be cleared.
Select = 0x0002,//All specified indexes will be selected. 有用
Deselect = 0x0004,//All specified indexes will be deselected. 有用
Toggle = 0x0008,//All specified indexes will be selected or
// deselected depending on their current state.
Current = 0x0010,//The current selection will be updated.
Rows = 0x0020,//All indexes will be expanded to span rows.
Columns = 0x0040,//All indexes will be expanded to span columns.
SelectCurrent = Select | Current,
ToggleCurrent = Toggle | Current,
ClearAndSelect = Clear | Select
};
Q_DECLARE_FLAGS(SelectionFlags, SelectionFlag)
Q_FLAG(SelectionFlags)
//Sets the model item index to be the current item, and emits currentChanged().
//当前项用于键盘导航和焦点指示它独立于任何选中的项,尽管选中的项也可以成为当前项。
//根据指定的命令 command,索引也可以成为当前选择的一部分。 //用代码的方式选中元素。
virtual void setCurrentIndex(const QModelIndex & index, //本函数会发出信号。
QItemSelectionModel::SelectionFlags command);
//Selects the model item index using the specified command,
// and emits selectionChanged(). //设置条目 index 的选中状态。
virtual void select(const QModelIndex & index,
QItemSelectionModel::SelectionFlags command);
virtual void select(const QItemSelection & selection,
QItemSelectionModel::SelectionFlags command);
//Selects the item selection using the specified command, and emits selectionChanged().
//同时设置范围 selection里的所有条目的选中状态。
//Clears the selection model. Emits selectionChanged() and currentChanged().
virtual void clear(); //以代码的方式取消对条目的选中。
void clearSelection(); //这三个函数的会发射的信号不一样。
//Clears the selection in the selection model. Emits selectionChanged().
virtual void clearCurrentIndex();
//Clears the current index. Emits currentChanged().
virtual void reset(); //Clears the selection model. Does not emit any signals.
Q_SIGNALS:
//This signal is emitted when the model is successfully set with setModel().
//void modelChanged(QAbstractItemModel * model); //这是成员函数
//void selectionChanged(const QItemSelection & selected, //这是成员函数
// const QItemSelection & deselected);
//每当选择发生变化时,就会发出这个信号。选择的变化被表示为未选中项的项选择以及选中项的项选择。
//请注意,当前索引的变化独立于选择。还请注意,当项目型重置时,此信号不会被发出。
// 那些保持被选中状态但索引发生变化的项并不被包含在“已选中”和“已取消选中”的列表中。
//因此,如果只是被选中项的索引发生了变化,
// 那么这个信号可能会被同时发出,既表示“已选中”,也表示“已取消选中”
//void currentChanged(const QModelIndex & current, const QModelIndex & previous);函数
//This signal is emitted whenever the current item changes. //本函数的参数很安全的,随便用
//The previous model item index is replaced by the current index as the
// selection's current item.
//Note that this signal will not be emitted when the item model is reset.
//This signal is emitted if the current(Column) item changes and
// its row(Column) is different to the row(Column) of the previous current item.
//Note that this signal will not be emitted when the item model is reset.
void currentRowChanged(const QModelIndex & current, const QModelIndex & previous);
void currentColumnChanged(const QModelIndex & current, const QModelIndex & previous);
//当被选中的条目换行了,或者换列了,触发本信号函数。
}; //完结 class QItemSelectionModel : public QObject
Q_DECLARE_OPERATORS_FOR_FLAGS(QItemSelectionModel::SelectionFlags)
QT_END_NAMESPACE
Q_DECLARE_METATYPE(QItemSelectionRange)
Q_DECLARE_METATYPE(QItemSelection)
#endif // QITEMSELECTIONMODEL_H
(11)
谢谢