在QML樹控件TreeView的使用(下)

在QML樹控件TreeView的使用(上)篇中,主要介紹了TreeView的使用以及數據的加載顯示,在本篇中,將主要介紹TreeModel類的增加數據與刪除數據,對樹控件TreeView的更新操作。
首先,在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
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章