首先组织QTreeView中每一项的数据结构,将要显示在QTreeView中的每一项的类定义为
class TreeItem : public QObject
{
Q_OBJECT
public:
TreeItem(const QList<QVariant> &data, QoSTreeItem *parent=0, QObject *parentObj = 0);
~QoSTreeItem();
void appendChild(QoSTreeItem *child);
QoSTreeItem *child(int row);
int childCount() const;
int columnCount() const;
QVariant data(int column) const;
int row() const;
QoSTreeItem *parent();
bool isChecked();
void setCheckState(bool state);
void setColumnData(int column, const QVariant &data);
public:
bool m_checked;
private:
TreeItem *parentItem; // 父节点
QList<TreeItem *> childItems; // 管理孩子节点的容器
QList<QVariant> itemData; // 子节点对应数值
};
//节点树中选中节点触发的复制粘贴按钮事件
void DisTreeView::onCopyPasteNode()
{
qDebug() << "Enter onCopyPasteNewNode";
QModelIndex index = this->currentIndex();
//当前节点
TreeItem *pCurItem = static_cast<QoSTreeItem*>(index.internalPointer());
//要添加的节点,添加的节点和当前节点是属于相同的树层级别
TreeItem *pAddNode = pCurItem->parent();
copyNode(pCurItem,pAddNode);
}
void DisTreeView::copyNode(TreeItem *pCurrentItem,TreeItem *pAddNodeRoot)
{
int ncount = pCurrentItem->childCount();
if( pCurrentItem->childCount() < 0 )
{
return;
}
QString strTagName = pCurrentItem->data(TagNameCol).toString();
QString strConfigValue = pCurrentItem->data(ConfigValCol).toString();
QString strValDomain = pCurrentItem->data(ValDomainCol).toString();
QString strDefault = pCurrentItem->data(DefaultValCol).toString();
QString strTagType = pCurrentItem->data(TagTypeCol).toString();
QList<QVariant> data;
data.clear();
data<<strTagName<<strConfigValue<<strValDomain<<strDefault<<strTagType;
TreeItem *newNode = new QoSTreeItem(data,pAddNodeRoot);
newNode->setCheckState(pCurrentItem->isChecked());
pAddNodeRoot->appendChild(newNode);
int rootCount = pCurrentItem->childCount();
for(int index = 0; index < rootCount; index ++)
{
copyNode(pCurrentItem->child(index),newNode);
}
}
本代码可用于普通树的复制粘贴,递归的内容在于每次将新建的节点作为下次新节点的父节点,相当于将树结构旋转90度,两颗要复制的树是属于兄弟树,源树只提供树的内容,不对源树做任何操作,只是在新树上进行插入。
之前有bug的原因在于以下几点:
- 对源树进行除提供数据以外的操作,导致在源树的节点上有新增添的节点内容。
- 在递归时将根节点作为每次的父节点,这样导致并不能构成层级关系,而是在原来的根目录上进行插入,应该是每次新添加的节点都是上次节点的子节点,如果该节点没有子节点,那么从兄弟节点又开始递归,直到达到最右边的叶子节点。