为啥不同的treeItems链接到相同的数据
Posted
技术标签:
【中文标题】为啥不同的treeItems链接到相同的数据【英文标题】:why are different treeItems linked to the same data为什么不同的treeItems链接到相同的数据 【发布时间】:2019-08-18 04:39:31 【问题描述】:我一直在尝试将树项及其子树复制到树视图中的另一个位置。
我终于可以成功地移动它们了。
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 data 函数中,我在其中恢复了容器的子树。
// 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;
树以正确的方式恢复。
但是现在我有一个问题,旧位置的树项和新位置的树项链接在一起,如果我对旧位置的树项进行任何更改,它也会影响新位置的树项。
【问题讨论】:
【参考方案1】:改变父级->appendChild(thisItem); to 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) 会很棒。
或任何替代解决方案。
【讨论】:
以上是关于为啥不同的treeItems链接到相同的数据的主要内容,如果未能解决你的问题,请参考以下文章
为啥通过同一个 COM 对象的不同接口检索到的 IUnknown* 指针具有相同的值?
为啥使用 UIImageJPEGRepresentation 和通过 localpath 获取图像之间的相同图像的数据大小/长度不同