我一直在尝试将树项及其子树复制到树视图中的另一个位置。
最后,我已经能够成功移动所有这些对象。
treeItem的头文件
class TreeItem
{
public:
explicit TreeItem( Container *data , TreeItem *parent = 0 );
~TreeItem();
TreeItem *parent();
void appendChild(TreeItem *child);
TreeItem& operator = (const TreeItem &item);
TreeItem *child(int iNumber);
int childCount() const;
int childNumber() const;
Container data() const ;
Container* GetContainer();
bool setData(Container* data , QVariant value);
void setContainer( Container* data);
bool insertChildren(int position, int count );
bool removeChildren( int position , int count );
void removeChild(int row);
void removeChild(TreeItem* itm);
QList<TreeItem*> children();
std::string getChildName(int row);
std::string getName();
int row() const;
void insertChild(int pos, TreeItem *child);
private:
QList<TreeItem*> childItems;
Container* itemData;
TreeItem* parentItem;
};
treeItem的Cpp文件
TreeItem::TreeItem( Container *data, TreeItem *parent )
{
parentItem = parent;
itemData = new Container;
*itemData = *data;
}
TreeItem::~TreeItem()
{
if (itemData != nullptr)
{
delete itemData;
}
qDeleteAll(childItems);
}
TreeItem& TreeItem::operator = (const TreeItem &item)
{
qDebug() << "TreeItem operator called";
// if( this->itemData == nullptr)
// this->itemData = new Container;
*this->itemData = *item.itemData;
this->childItems = item.childItems;
this->parentItem = item.parentItem;
return *this;
}
TreeItem *TreeItem::parent()
{
return parentItem;
}
TreeItem *TreeItem::child(int iNumber)
{
return childItems.value(iNumber);
}
int TreeItem::childCount() const
{
return childItems.count();
}
int TreeItem::childNumber() const
{
if (parentItem)
return parentItem->childItems.indexOf(const_cast<TreeItem*> (this));
return 0;
}
Container TreeItem::data() const
{
return *itemData;
}
bool TreeItem::setData( Container* data , QVariant value )
{
//*itemData = *data; // Do Not !!!! uncomment this ///////////////////////////as it will set the value of default container constructor.
itemData->SetName(value.toString().toStdString() );
return true;
}
bool TreeItem::insertChildren(int position, int count)
{
if (position < 0 || position > childItems.count())
return false;
Container cont;
TreeItem *item = new TreeItem(&cont, this);
childItems.insert(position, item);
return true;
}
bool TreeItem::removeChildren(int position, int count)
{
if (position < 0 || position > childItems.count())
return false;
for (int row = 0; row < count; ++row)
{
delete childItems.takeAt(position);
}
return true;
}
void TreeItem::setContainer( Container* cont)
{
*itemData = *cont;
}
void TreeItem::appendChild(TreeItem *node)
{
childItems.append( node );
}
int TreeItem::row() const
{
// qDebug() << "The child count = " << parentItem->childItems.indexOf(const_cast<TreeItem*>(this));
if (parentItem)
return parentItem->childItems.indexOf( const_cast<TreeItem*>(this) );
return 0;
}
void TreeItem::removeChild(int row)
{
// qDebug() << "The Row Number" << row;
// childItems.removeAt(row);
delete childItems.takeAt(row);
}
void TreeItem::insertChild(int pos, TreeItem *child)
{
childItems.insert(pos, child);
child->parentItem = this;
}
void TreeItem::removeChild(TreeItem* itm)
{
childItems.removeOne(itm);
}
std::string TreeItem::getChildName(int row)
{
return childItems.value(row)->getName();
}
std::string TreeItem::getName()
{
return itemData->GetName();
}
Container* TreeItem::GetContainer()
{
return itemData;
}
QList<TreeItem*> TreeItem::children()
{
return childItems;
}
这是我在树结构中为树项目的子容器构建树的功能。
void TreeModel::buildTree(TreeItem * pItem, QDataStream & ds) const
{
if (pItem == NULL)
return;
ds << reinterpret_cast<qlonglong>(pItem);
ds << pItem->childCount();
foreach(TreeItem* childItem, pItem->children())
{
buildTree(childItem, ds);
}
}
这是在Drop mime数据功能中,在这里我可以还原容器的子树。
// count is the number of child containers of the tree item
TreeItem *node;
//qDebug() << "The row" << row << parentNode->data().GetName().c_str() ;
for (int i = 0; i < count; ++i) {
// Decode data from the QMimeData
qlonglong nodePtr;
int childCount;
stream >> nodePtr;
stream >> childCount;
node = reinterpret_cast<TreeItem *>(nodePtr);
// Adjust destination row for the case of moving an item
// within the same parent, to a position further down.
// Its own removal will reduce the final row number by one.
if (node->row() < row && parentNode == node->parent())
--row;
TreeItem *nodeNew = new TreeItem(node->GetContainer(), node->parent());
nodeNew->setContainer(node->GetContainer());
// Insert at new position
//qDebug() << "Inserting into" << parent << row;
beginInsertRows(parent, row, row);
parentNode->insertChild(row, nodeNew);
endInsertRows();
for (int k = 0; k < childCount; k++)
{
restoreTree(stream, nodeNew);
}
++row;
}
这是还原子树的功能。
TreeItem * TreeModel::restoreTree(QDataStream & ds , TreeItem* parent) const
{
Container cont;
// Restore the info from the stream
int childCount;
qlonglong nodePtr;
ds >> nodePtr;
ds >> childCount;
TreeItem *currentItem = reinterpret_cast<TreeItem *>(nodePtr);
if (currentItem == nullptr)
return nullptr;
TreeItem *thisItem = new TreeItem(currentItem->GetContainer(), currentItem->parent() );
thisItem->setContainer(currentItem->GetContainer());
//*thisItem = *currentItem;
parent->appendChild(thisItem);
for (auto nChild = 0; nChild < childCount; ++nChild)
{
TreeItem* oldChild = restoreTree(ds, thisItem);
if (oldChild != nullptr)
{
TreeItem *pChild = new TreeItem( oldChild->GetContainer() , oldChild->parent() );
pChild->setContainer(oldChild->GetContainer());
thisItem->appendChild(pChild);
qDebug() << "Appending child";
}
}
return thisItem;
}
以正确的方式恢复树。
但是现在我有一个问题,旧位置的树项目和新位置的树项目链接在一起,如果我对旧位置的树项目进行任何更改,那么它也会影响新位置的TreeItem。
答案 0 :(得分:1)
更改父项-> appendChild(thisItem);到parent-> insertChild(row,thisItem); BuildTree函数现在可以解决问题了。
TreeItem * TreeModel::restoreTree(QDataStream & ds , TreeItem* parent , int row) const
{
Container cont;
// Restore the info from the stream
int childCount;
qlonglong nodePtr;
QModelIndex parentIndex;
ds >> nodePtr;
ds >> childCount;
TreeItem *currentItem = reinterpret_cast<TreeItem *>(nodePtr);
if (currentItem == nullptr)
return nullptr;
TreeItem *thisItem = new TreeItem(currentItem->GetContainer(), currentItem->parent() );
thisItem->setContainer(currentItem->GetContainer());
//*thisItem = *currentItem;
// parent->appendChild(thisItem);
parent->insertChild(row, thisItem);
for (auto nChild = 0; nChild < childCount; ++nChild)
{
restoreTree(ds, thisItem , nChild);
}
return thisItem;
}
如果有人可以解释parent-> appendChild(thisItem)之间的区别,那么尝试并找到可行的解决方案就更容易了。到parent-> insertChild(row,thisItem)会很棒。
或任何其他解决方案。