使用list实现QTreeWidget树节点操作的撤销和恢复

对QTreeWidget中树节点的创建、删除和移动操作的撤销和恢复:

当每次操作成功之后保存当前操作的节点指针,父节点指针(为nullptr时默认认为父节点是QTreeWidget* )和当前操作节点在父节点的孩子节点中的位置

也可以使用Qt库中

  • QtUndoCommand 
  • QtUndoStack - QtUndoCommand实现相关操作
 //伪代码...
 // .h:

 enum E_StepType{ //步骤类型
    ST_MoveUp=0X00,
    ST_MoveDown=0X01,
    ST_LevelUp=0X02,
    ST_LevelDown=0X03,
    ST_Create=0X04,
    ST_Delete=0X05,
    ST_Unknow=-1
};


struct StepInfo{ //步骤信息
    E_StepType type=ST_Unknow;
    QTreeWidgetItem* pParentItem=nullptr;
    int itemIndex=-1;
    QTreeWidgetItem* targetItem=nullptr;
};


 QList<StepInfo> stepInfoList;
 int steplistPos=0; //步骤位置


 void undoTreeWidget(); // 撤销当前操作步骤并保存

 void redoTreeWidget(); // 重做保存的撤销操作

 void pushStepInfo(const StepInfo& stepInfo); // 保存操作项






// .cpp:

void undoTreeWidget(){ //撤销
    auto bgn=this->stepInfoList.begin()+this->steplistPos;
    if(bgn==this->stepInfoList.end()) //到栈底
        return;

    switch (E_StepType(bgn->type)) {
    case ST_Create:
        // *bgn得到项位置信息...
        // takeTopLevelItem(int index)或pItemParent->takeChild(int index)
        break;

    case ST_MoveUp:
    case ST_MoveDown:
    case ST_LevelUp:
    case ST_LevelDown:{
        auto& startPos=*bgn;
        ++this->steplistPos;
        ++bgn;
        auto& endPos=*bgn;
        
        // 通过startPos和endPos得到前后位置信息
        // QTreeWidget::takeTopLevelItem(int index)或QTreeWidgetItem::takeChild(int                     
        //     index)
       }
        break;

    case ST_Delete:
        // *bgn 得到项信息
        // insertItem(int index, QTreeWidgetItem *item);
        break;

    default:
        break;
    }
    ++this->steplistPos;
}


void redoTreeWidget(){ //重做
    auto bgn=this->stepInfoList.begin()+this->steplistPos;
    if(bgn==this->stepInfoList.begin()) //到栈底
        return;
    --bgn;
    --this->steplistPos;

    switch (E_StepType(bgn->type)) {
    case ST_Create:
        // *bgn 得到项信息
        // insertItem(int index, QTreeWidgetItem *item);
        break;

    case ST_MoveUp:
    case ST_MoveDown:
    case ST_LevelUp:
    case ST_LevelDown:{
        auto& startPos=*bgn;  
        --bgn;
        --this->steplistPos;
        auto& endPos=*bgn;
     
        // 通过startPos和endPos得到前后位置信息
        // takeTopLevelItem(int index)或pItemParent->takeChild(int index)

       }
        break;

    case ST_Delete:
        // *bgn得到项位置信息...
        // takeTopLevelItem(int index)或pItemParent->takeChild(int index)
        break;
       
    default:
        break;
    }
}

//记录操作项信息:若移动、删除、创建成功保存记录,移动操作需要保存移动前后的位置信息
void pushStepInfo(const StepInfo& stepInfo){
    this->stepInfoList.insert(this->steplistPos,stepInfo);
    if(this->steplistPos!=0){ //移除重做项
        for(int i=0;i<this->steplistPos;++i){

            StepInfo& step= this->stepInfoList.front();
            this->stepInfoList.pop_front();

            if(step.type!=E_StepType::ST_Create)
                continue;
            if(step.targetItem->treeWidget()==nullptr)
                delete step.targetItem;
        }
        this->steplistPos=0;
    }

  • 2
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值