需要实现的函数
class ItemModel : public QAbstractTableModel
{
Q_OBJECT
public:
ItemModel(QObject* parent = Q_NULLPTR);
~ItemModel();
virtual int rowCount(const QModelIndex& parent = QModelIndex()) const override;
virtual int columnCount(const QModelIndex& parent = QModelIndex()) const override;
virtual QVariant data(const QModelIndex& index, int role = Qt::DisplayRole) const override;
virtual Qt::ItemFlags flags(const QModelIndex& index) const override;
virtual bool setData(const QModelIndex& index, const QVariant& value, int role = Qt::DisplayRole) override;
virtual QVariant headerData(int section, Qt::Orientation orientation, int role = Qt::DisplayRole) const override;
void setData(ItemData data);
private:
QList<ItemData> m_datas;
QStringList m_header;
};
其中ItemData结构体的定义如下
class ItemData {
public:
int Id;
int Count;
bool IsEnable;
};
实现
ItemModel::ItemModel(QObject* parent)
: QAbstractTableModel(parent)
{
m_header << "Id" << "Name" << "state";
}
ItemModel::~ItemModel()
{
}
int ItemModel::rowCount(const QModelIndex& parent) const
{
return m_datas.count();
}
int ItemModel::columnCount(const QModelIndex& parent) const
{
return 3;
}
QVariant ItemModel::data(const QModelIndex& index, int role) const
{
if (!index.isValid())
return QVariant();
int nRow = index.row();
int nColumn = index.column();
ItemData data = m_datas.at(nRow);
switch (role)
{
case Qt::DisplayRole:
{
if (nColumn == 0)
return data.Id;
if (nColumn == 1)
return data.Count;
return "";
}
case Qt::EditRole:
{
if (nColumn == 1)
return data.Count;
return "";
}
case Qt::CheckStateRole:
{
if (nColumn == 2)
return data.IsEnable ? Qt::Checked : Qt::Unchecked;
}
default:
return QVariant();
}
return QVariant();
}
Qt::ItemFlags ItemModel::flags(const QModelIndex& index) const
{
if (!index.isValid())
return QAbstractItemModel::flags(index);
Qt::ItemFlags flags = Qt::ItemIsEnabled | Qt::ItemIsSelectable;
if (index.column() == 1)
flags |= Qt::ItemIsEditable;
if (index.column() == 2)
flags |= Qt::ItemIsUserCheckable;
return flags;
}
QVariant ItemModel::headerData(int section, Qt::Orientation orientation, int role ) const
{
if (role == Qt::DisplayRole) {
if (orientation == Qt::Horizontal) {
return m_header.at(section);
}
}
return QAbstractTableModel::headerData(section, orientation, role);
}
void ItemModel::setData(ItemData data)
{
m_datas.append(data);
beginResetModel();
endResetModel();
}
bool ItemModel::setData(const QModelIndex& index, const QVariant& value, int role )
{
if (!index.isValid())
return false;
int nColumn = index.column();
ItemData data = m_datas.at(index.row());
switch (role)
{
case Qt::DisplayRole:
{
if (nColumn == 0)
{
data.Id = value.toInt();
m_datas.replace(index.row(), data);
emit dataChanged(index, index);
return true;
}
}
case Qt::EditRole:
{
if (nColumn == 1) {
data.Count = value.toInt();
m_datas.replace(index.row(), data);
emit dataChanged(index, index);
return true;
}
}
case Qt::CheckStateRole:
{
if (nColumn == 2)
{
data.IsEnable = (value.toInt() == Qt::Checked);
m_datas.replace(index.row(), data);
emit dataChanged(index, index);
return true;
}
}
default:
return false;
}
return false;
}
使用
ui.tableView->setSelectionBehavior(QAbstractItemView::SelectRows);
ui.tableView->setModel(&m_item_model);
for (size_t i = 0; i < 10; i++)
{
ItemData data;
data.Id = i;
data.Count = i * 2;
data.IsEnable = true;
m_item_model.setData(data);
}
后记
- 由于是Demo ,所以上述代码的格式上可能比较随意
- 在使用的过程中,发现同时使用QAbstractTableModel 和 QStyledItemDelegate时,只会触发QStyledItemDelegate的paint调用,还不知道具体的原因,有知道的大佬欢迎评论区留言
- 针对第二点可以在paint函数中自己去绘制控件
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 阿里最新开源QwQ-32B,效果媲美deepseek-r1满血版,部署成本又又又降低了!
· AI编程工具终极对决:字节Trae VS Cursor,谁才是开发者新宠?
· 开源Multi-agent AI智能体框架aevatar.ai,欢迎大家贡献代码
· Manus重磅发布:全球首款通用AI代理技术深度解析与实战指南
· 被坑几百块钱后,我竟然真的恢复了删除的微信聊天记录!