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實戰派學習群