版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/Shado_walker/article/details/58182138
在QML树控件TreeView的使用(上)篇中,主要介绍了TreeView的使用以及数据的加载显示,在本篇中,将主要介绍TreeModel类的增加数据与删除数据,对树控件TreeView的更新操作。
首先,在TreeView的某个节点增加数据如下:
在树TreeView的某一个节点删除数据(删除该行与其子树)如下:
以上,完成了在树TreeView中将数据增加和删除并更新到界面进行显示。
要注意的是,在对树进行增加或删除数据后,要对增加或删除的行进行更新,才能及时的对界面进行更新,追加数据时的更新调用:
void QAbstractItemModel::beginInsertRows(const QModelIndex &parent, int first, int last);
和
void QAbstractItemModel::endInsertRows();函数。
删除时的更新调用:
void QAbstractItemModel::beginRemoveRows(const QModelIndex &parent, int first, int last);
和
void QAbstractItemModel::endRemoveRows()函数。
如果更新时没有调用这两组函数,界面数据只能在树下次收缩在展开后更新到界面。
将以上函数增加到上篇的类TreeModel中,加入测试数据,选中某个节点,然后点击【更新】按钮,即可先删除该节点下的所有子节点,然后插入自己的测试数据,这样,就完成了树的更新。
在qml文件中增加按钮响应,代码如下:
效果如下:
以上的【更新】按钮响应TreeController.cpp中的addDataClicked(QModelIndex index)函数如下:
void TreeController::addDataClicked(QModelIndex index)
{
m_model.appendChild(index);
}
以上,完成了QML中TreeView的所有操作。
完整的demo程序工程实例地址:http://download.csdn.net/detail/shado_walker/9761108
首先,在TreeView的某个节点增加数据如下:
void TreeModel::appendChild(const QModelIndex& index)
{
TreeItem* clickItem = static_cast<TreeItem*>(index.internalPointer());
/*beginRemoveRows(index, 0, 0);
clickItem->deleteAllChild();
endRemoveRows();*/
removeRows(0, clickItem->childCount(), index);
QList<QVariant> TestItem;
TestItem.append("TestItem");
TestItem.append("TI");
TreeItem* TestItem_Item = new TreeItem(TestItem, clickItem);
QList<QVariant> TestItem2;
TestItem2.append("TestItem2");
TestItem2.append("TI2");
TreeItem* TestItem_Item2 = new TreeItem(TestItem2, TestItem_Item);
beginInsertRows(index, 0, 0);
TestItem_Item->appendChild(TestItem_Item2);
clickItem->appendChild(TestItem_Item);
endInsertRows();
}
在树TreeView的某一个节点删除数据(删除该行与其子树)如下:
bool TreeModel::removeRows(int row, int count, QModelIndex parent)
{
if (parent.isValid())
{
for (int r = row; r < (row + count); ++r)
{
QModelIndex idxRemove = parent.child(r, 0);
TreeItem* fiRemove = static_cast<TreeItem*>(idxRemove.internalPointer());
if (idxRemove.child(0, 0).isValid())
{
bool childRemoved = removeRows(0, fiRemove->childCount(), idxRemove);
}
}
TreeItem* fiParent = static_cast<TreeItem*>(parent.internalPointer());
int last = 0;
if (row + count - 1 > 0)
{
last = row + count - 1;
}
beginRemoveRows(parent, row, last);
fiParent->deleteAllChild();
endRemoveRows();
return true;
}
else
{
for (int r = row; r < (row + count); ++r)
{
TreeItem* slnItem = m_rootItem->child(r);
bool projectRemoved = removeRows(0, slnItem->childCount(), index(r, 0, QModelIndex()));
}
if ((row + count) > 0)
{
beginRemoveRows(QModelIndex(), row, row + count - 1);
m_rootItem->deleteAllChild();
endRemoveRows();
}
return true;
}
return false;
}
以上,完成了在树TreeView中将数据增加和删除并更新到界面进行显示。
要注意的是,在对树进行增加或删除数据后,要对增加或删除的行进行更新,才能及时的对界面进行更新,追加数据时的更新调用:
void QAbstractItemModel::beginInsertRows(const QModelIndex &parent, int first, int last);
和
void QAbstractItemModel::endInsertRows();函数。
删除时的更新调用:
void QAbstractItemModel::beginRemoveRows(const QModelIndex &parent, int first, int last);
和
void QAbstractItemModel::endRemoveRows()函数。
如果更新时没有调用这两组函数,界面数据只能在树下次收缩在展开后更新到界面。
将以上函数增加到上篇的类TreeModel中,加入测试数据,选中某个节点,然后点击【更新】按钮,即可先删除该节点下的所有子节点,然后插入自己的测试数据,这样,就完成了树的更新。
在qml文件中增加按钮响应,代码如下:
Rectangle {
width: 70
height: 30
color: "red"
anchors.top: view.bottom
anchors.topMargin: 50
anchors.horizontalCenter: view.horizontalCenter
Button {
anchors.fill: parent
text: qsTr("更新")
onClicked: {
//addDataClicked(QModelIndex index)
root.ctrl.addDataClicked(view.currentIndex);
}
}
}
以上Rectangle与上篇中的TreeView同级。
效果如下:
以上的【更新】按钮响应TreeController.cpp中的addDataClicked(QModelIndex index)函数如下:
void TreeController::addDataClicked(QModelIndex index)
{
m_model.appendChild(index);
}
以上,完成了QML中TreeView的所有操作。
完整的demo程序工程实例地址:http://download.csdn.net/detail/shado_walker/9761108