《QTreeView实现行列的插入与删除》:系列教程之十一

本文属于《QTreeView使用系列教程》之一,欢迎查看其它文章。

一、概述

QTreeView行列的插入与删除,若使用QTreeView+QStandardItemModel方式,或者QTreeWidget方式实现的话,直接调用相应的方法就行了。而采用QTreeView+自定义model方式的话,需要我们自己实现数据的插入与删除,故在本节中,我们主要对此方式进行说明。

前面已经对如何实现自定义model,进行了说明,所以对这部分不再赘述。

行与列的插入或删除,比较类似,所以我们只对行操作进行说明,列操作可参考行操作实现。

二、实现插入行

我们重写QAbstractItemModel类insertRows()函数,使用beginInsertRows(),endInsertRows()对实际数据插入操作进行包围,类似于告知View插入开始与结束。

bool TreeModel::insertRows(int row, int count, const QModelIndex &parent)
{
    TreeItem *parentItem = itemFromIndex(parent);

    beginInsertRows(parent, row, row + count - 1);

    for (int i = 0; i < count; i++)
    {
        TreeItem* item = new TreeItem(parentItem);
        parentItem->insertChild(row + i, item);

        // 填充item数据
        if (parentItem->getType() == TreeItem::PROVINCE)
        {
            TreeItem::fillPersonData(item,
                                     QString("new name%1").arg(i),
                                     "man",
                                     25,
                                     "123456789");
        }
        else if (parentItem->getType() == TreeItem::UNKNOWN) // root
        {
            TreeItem::fillProvinceData(item, QString("new Province%1").arg(i));
        }
    }

    endInsertRows();
    return true;
}

beginInsertRows的参数,分别是父节点索引,插入点的行号,结束插入的行号。具体含义,下面的qt帮助截图,可以查看。

void beginInsertRows(const QModelIndex &parent, int first, int last);

在这里插入图片描述

另外,需要调用到的几个函数,我们在TreeItem中进行定义

void TreeItem::insertChild(int row, TreeItem* item)
{
    _children.insert(row, item);
}

void TreeItem::fillPersonData(TreeItem *item, const QString& name, const QString& sex, int age, const QString& phone)
{
    Person* per = new Person();
    per->name = name;
    per->sex = sex;
    per->age = age;
    per->phone = phone;

    item->setPtr(per);    // 保存数据指针
    item->setType(TreeItem::PERSON);  // 设置节点类型为PERSON
}

void TreeItem::fillProvinceData(TreeItem *item, const QString &name)
{
    Province* pro = new Province();
    pro->name = name;

    item->setPtr(pro);    // 保存数据指针
    item->setType(TreeItem::PROVINCE);  // 设置节点类型为PROVINCE
}

然后,我们在View的右键菜单槽函数中,调用model插入行

void MainWindow::onActionInsert()
{
    QModelIndex index = treeView->currentIndex();
    if(index.isValid())
    {
        treeView->model()->insertRow(index.row(), index.parent());
    }
}

小贴士:

此处调用的insertRow(),与TreeModel中重写的insertRows(),有何关联?请看下面实现:

inline bool QAbstractItemModel::insertRow(int arow, const >QModelIndex &aparent)
{ return insertRows(arow, 1, aparent); }

调用insertRow()会自动调用我们重写的insertRows()。

到此,我们实现了插入行。

三、实现删除行

接下来,实现删除行,就更简单了。

类比于插入行,我们也重写QAbstractItemModel类removeRows()函数,使用beginRemoveRows(),endRemoveRows()对实际数据删除操作进行包围,类似于告知View删除开始与结束。

bool TreeModel::removeRows(int row, int count, const QModelIndex &parent)
{
    TreeItem *parentItem = itemFromIndex(parent);

    beginRemoveRows(parent, row, row + count - 1);

    for (int i = 0; i < count; i++)
    {
        parentItem->removeChild(row);
    }

    endRemoveRows();
    return true;
}

然后,我们在TreeItem中定义删除行函数

void TreeItem::removeChild(int row)
{
    TreeItem *item = _children.at(row);
    delete item;
    _children.removeAt(row);
}

然后,我们在View的右键菜单槽函数中,调用model删除行

void MainWindow::onActionRemove()
{
    QModelIndex index = treeView->currentIndex();
    if(index.isValid())
    {
        treeView->model()->removeRow(index.row(), index.parent());
    }
}

removeRow()与removeRows()的关系,与上文中小贴士提到的insertRow()与insertRows()关系雷同,不再赘述。

到此,我们实现了删除行。

四、结束

运行效果:
在这里插入图片描述



若对你有帮助,欢迎点赞、收藏、评论,你的支持就是我的最大动力!!!

同时,阿超为大家准备了丰富的学习资料,欢迎关注公众号“超哥学编程”,即可领取。

本文涉及工程代码,公众号回复:34InsertRemoveRow,即可下载。

在这里插入图片描述

  • 7
    点赞
  • 38
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

百里杨

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值