c++如何用QAbstractTableModel来实现QStandardItemModel的功能
时间: 2024-03-06 21:47:46 浏览: 119
Qt QTreeView使用-QStandardItemModel的使用
`QStandardItemModel` 是 `Qt` 提供的一个很方便的模型类,它可以用来存储和管理 `QStandardItem` 的列表。但是,如果你需要更精细的控制和自定义功能,你可能需要使用 `QAbstractTableModel` 来实现自己的模型类。
以下是一个简单的例子,演示如何用 `QAbstractTableModel` 实现 `QStandardItemModel` 的基本功能:
```cpp
class MyTableModel : public QAbstractTableModel
{
public:
MyTableModel(QObject* parent = nullptr) : QAbstractTableModel(parent) {}
int rowCount(const QModelIndex& parent = QModelIndex()) const override
{
if (parent.isValid()) {
return 0;
}
return m_items.count();
}
int columnCount(const QModelIndex& parent = QModelIndex()) const override
{
if (parent.isValid()) {
return 0;
}
return m_headers.count();
}
QVariant data(const QModelIndex& index, int role = Qt::DisplayRole) const override
{
if (!index.isValid()) {
return QVariant();
}
if (role == Qt::DisplayRole || role == Qt::EditRole) {
return m_items[index.row()][index.column()].text();
}
return QVariant();
}
bool setData(const QModelIndex& index, const QVariant& value, int role = Qt::EditRole) override
{
if (!index.isValid()) {
return false;
}
if (role == Qt::EditRole) {
m_items[index.row()][index.column()].setText(value.toString());
emit dataChanged(index, index);
return true;
}
return false;
}
QVariant headerData(int section, Qt::Orientation orientation, int role = Qt::DisplayRole) const override
{
if (role == Qt::DisplayRole && orientation == Qt::Horizontal) {
return m_headers[section];
}
return QVariant();
}
Qt::ItemFlags flags(const QModelIndex& index) const override
{
if (!index.isValid()) {
return Qt::NoItemFlags;
}
return QAbstractTableModel::flags(index) | Qt::ItemIsEditable;
}
void setRowCount(int count)
{
if (count == rowCount()) {
return;
}
if (count < rowCount()) {
beginRemoveRows(QModelIndex(), count, rowCount() - 1);
m_items.resize(count);
endRemoveRows();
} else {
beginInsertRows(QModelIndex(), rowCount(), count - 1);
m_items.resize(count);
endInsertRows();
}
}
void setColumnCount(int count)
{
if (count == columnCount()) {
return;
}
if (count < columnCount()) {
beginRemoveColumns(QModelIndex(), count, columnCount() - 1);
m_headers.resize(count);
for (auto& row : m_items) {
row.resize(count);
}
endRemoveColumns();
} else {
beginInsertColumns(QModelIndex(), columnCount(), count - 1);
m_headers.resize(count);
for (auto& row : m_items) {
row.resize(count);
}
endInsertColumns();
}
}
void setHeaderData(int section, Qt::Orientation orientation, const QVariant& value, int role = Qt::EditRole) override
{
if (role != Qt::EditRole || orientation != Qt::Horizontal || section < 0 || section >= columnCount()) {
return;
}
m_headers[section] = value.toString();
emit headerDataChanged(orientation, section, section);
}
private:
QList<QList<QStandardItem>> m_items;
QStringList m_headers;
};
```
在这个例子中,我们定义了一个叫做 `MyTableModel` 的类,它继承自 `QAbstractTableModel`。它包含一个 `QList<QList<QStandardItem>>` 类型的成员变量 `m_items`,用于存储所有的数据项,以及一个 `QStringList` 类型的成员变量 `m_headers`,用于存储所有的列标题。
我们重写了 `rowCount()` 和 `columnCount()` 函数来返回行数和列数。在 `data()` 函数中,我们返回指定单元格的数据,同时处理了 `Qt::DisplayRole` 和 `Qt::EditRole` 两种角色。在 `setData()` 函数中,我们设置指定单元格的数据,并发出 `dataChanged()` 信号来通知视图更新界面。在 `headerData()` 函数中,我们返回指定列的标题。在 `flags()` 函数中,我们指定单元格的属性,使其可编辑。
最后,我们还实现了 `setRowCount()`、`setColumnCount()` 和 `setHeaderData()` 函数,用于动态改变行数、列数和列标题。
希望这个例子能帮到你!
阅读全文