1,简介
之前发布的两篇自定义model的文章,有小伙伴下载源码后发现元素不能编辑。
确实是的,因为我自己都是用来展示数据,没做这个。
这篇文章实现item编辑功能。
2,效果
但是由于我这个示例,真实数据只有名称、三门课成绩,后面的展示数据都是根据这些实时计算出来的。
因此只有真实数据支持修改,而且修改后 其他推算型数据也会自动刷新。
这点需要注意。
3,代码
主要需处理下面几个地方:
1,QTreeView 也要设置编辑操作类型:
ui->treeView->setEditTriggers(QTreeView::DoubleClicked); //单元格双击编辑
2,元素的 flags 要加可编辑属性: Qt::ItemIsEditable
Qt::ItemFlags TreeModel::flags(const QModelIndex &index) const
{
if (!index.isValid())
return 0;
//节点是否允许编辑
Qt::ItemFlags flags = QAbstractItemModel::flags(index);
flags |= Qt::ItemIsEditable;
return flags;
}
3,另外data 函数里,也需要对 Qt::EditRole 处理下,否则打开编辑框时,默认是空白。
这里我们让编辑框默认就显示 item 的文本。
QVariant TreeModel::data(const QModelIndex &index, int role) const
{
if (!index.isValid())
return QVariant();
TreeItem *item = static_cast<TreeItem*>(index.internalPointer());
if (role == Qt::DisplayRole)
{
return item->data(index.column());
}
else if (role == Qt::EditRole)
{
//元素打开编辑框时,显示的内容,如果没有这行,编辑框出现时默认为空白
return item->data(index.column());
}
else if( role == Qt::TextAlignmentRole )
{
if( index.column() == 0 )
{
//第1列左对齐
return QVariant(Qt::AlignVCenter | Qt::AlignLeft);
}
else if( index.column() > 0 && index.column() < 6 )
{
//第2~6列右对齐
return QVariant(Qt::AlignVCenter | Qt::AlignRight);
}
else
{
//其他列居中对齐
return QVariant(Qt::AlignCenter);
}
}
else if(role == Qt::TextColorRole)
{
if(index.column() == 6)
{
QString str = item->data(6).toString();
if(str == QStringLiteral("不合格"))
{
//第7列(是否合格)如果不合格就设文本为红色
return QVariant(QColor("#FF0000"));
}
}
return QVariant();
}
return QVariant();
}
4,setData 函数,就是编辑框输入完后,应用时走的逻辑,我们去修改真实数据:
bool TreeModel::setData(const QModelIndex &index, const QVariant &value, int role)
{
if (index.isValid() && role == Qt::EditRole)
{
TreeItem *item = static_cast<TreeItem*>(index.internalPointer());
item->setData(index.column(), value);
emit dataChanged(index, index);
return true;
}
return false;
}
其中调用TreeItem 进行真正的修改:
可以看到真实数据只有这几个,因此也只能修改这几个数据。其他数据会在显示时自动计算的。
void TreeItem::setData(int column, QVariant value)
{
if(mLevel == 1)
{
//一级节点,班级
if(column == 0)
{
CLASS* c = (CLASS*)mPtr;
c->name = value.toString();
}
}
else if(mLevel==2)
{
//二级节点学生信息
STUDENT* s = (STUDENT*)mPtr;
switch (column)
{
case 0: s->name = value.toString();break;
case 1: s->score1 = value.toInt();break;
case 2: s->score2 = value.toInt();break;
case 3: s->score3 = value.toInt();break;
default:
return ;
}
}
}
4,源码
写作不易,源码有偿提供:(注意链接是全套专栏完整源码,请勿重复下载)
https://mianbaoduo.com/o/bread/YZuTk5dx
欢迎入群交流:
群号码:1149411109 (若满加2群:917341904)
群名称:Qt实战派学习群