在Qt中,有许多模式来解决一些问题,比如代理、比如图元等。今天本文就简单讲解一下 模型/视图 模式中的数据存储。
为什么需要 模型/视图模式
当需要在用户界面中显示大量的数据时,需要一种有效的方法来管理和呈现这些数据。模型/视图(Model/View)编程模式是一种常见的解决方案,它将数据存储在模型中,并将视图用于显示和编辑这些数据。
模型/视图编程模式的基本思想是,将数据和用户界面分离。模型负责存储和管理数据,而视图负责将数据呈现给用户,并允许用户与数据进行交互。模型和视图之间通过一个框架进行连接,该框架允许模型和视图之间进行通信,并协调它们的工作。
简单介绍一下 模型 / 视图模式吧~
在 Qt 中,模型/视图框架由 QAbstractItemModel 和 QAbstractItemView 两个类组成。QAbstractItemModel 是一个抽象类,提供了用于在子类中实现特定类型的模型的接口。QAbstractItemView 也是一个抽象类,提供了用于在子类中实现特定类型的视图的接口。通常情况下,开发人员会使用 Qt 中提供的现成的子类,如 QStandardItemModel 和 QTreeView。
在模型/视图编程模式中,模型由一系列的数据项组成。每个数据项都有一个唯一的索引,用于在模型中进行定位。索引由一个行号和一个列号组成,这个索引叫做 QModelIndex。视图根据模型中的数据项来生成用户界面。视图通常包含了一个可滚动的列表或表格,以及用于显示和编辑数据项的控件。
当数据项发生变化时,模型将会发出信号通知视图进行更新。这些信号包括 dataChanged、rowsInserted、rowsRemoved 等。视图监听这些信号,并相应地更新用户界面。此外,视图也可以监听用户的输入事件,并通过模型来更新数据。
上面都是说的一些废话,下面开始进入正题
在模型/视图编程模式中,模型负责存储和管理数据。为了能够在视图中显示数据,模型需要提供一些方法来访问和操作数据。其中一个重要的方法就是 data()。
data() 方法用于获取模型中指定索引位置的数据。该方法接收一个 QModelIndex 参数,表示要获取数据的位置。QModelIndex 由行号和列号组成,指定了数据在模型中的位置。
data() 方法返回一个 QVariant 类型的值,表示指定位置的数据。QVariant 是一个通用的值类型,可以包含各种类型的数据。例如,如果模型中存储的是字符串类型的数据,则 data() 方法返回一个包含该字符串的 QVariant 对象。
在实现自定义模型时,可以重载 data() 方法,以便在需要时提供特定的数据。通常情况下,data() 方法需要根据索引位置返回相应的数据。如果索引无效或数据无法访问,则应返回一个空的 QVariant 对象。
视图通常在需要显示模型中的数据时调用 data() 方法。例如,QTableView 中的每个单元格都需要显示一个数据项。当视图需要更新单元格时,它会调用模型的 data() 方法,以获取该单元格对应的数据。视图可以根据需要格式化数据,例如使用不同的字体、颜色或对齐方式。
好像还是很模糊,举个列子吧。
比如现在有一棵树,我们想做到点击不同级别的树,可以操作不同的内容
如何做到这一件事情呢?
可以给每一个项添加一个data,比如:
item1->setData(Qt::UserRole, type1)
item2->setData(Qt::UserRole, type2)
然后再item click 事件中去处理它。就可以达到处理不同的事物。
这种模式非常简单明了和方便。
再比如:
假设我们有一个存储颜色的数据模型,其中每个数据项包含一个颜色值。我们想要在视图中将不同的颜色用不同的字体颜色来显示,可以通过重载 data() 方法来实现。
首先,在模型中定义一个枚举类型,用于表示每个数据项的不同颜色:
enum ColorRole {
RedRole = Qt::UserRole + 1,
GreenRole,
BlueRole
};
然后,重载 data() 方法,根据不同的颜色值返回不同的字体颜色
QVariant ColorModel::data(const QModelIndex& index, int role) const
{
if (!index.isValid()) {
return QVariant();
}
if (role == Qt::DisplayRole || role == Qt::EditRole) {
QColor color = index.data(ColorRole::RedRole).toInt(),
index.data(ColorRole::GreenRole).toInt(),
index.data(ColorRole::BlueRole).toInt());
QString html = QString("<font color='%1'>%2</font>")
.arg(color.name())
.arg(color.name());
return html;
}
return QVariant();
}
在这个例子中,通过 QModelIndex 参数获取要显示的数据项的颜色值,并使用 QColor 类型来将该值转换为颜色。然后,我们使用 QString 类型构建一个 HTML 标记,用于设置字体颜色,并将其返回为 QVariant 对象。
这样就可以非常灵活的做到字体颜色的更换。