展示文件系统及勾选联动——Qt

前言

为了实现如标题的功能,我真的是差点放弃了,还好我没放弃,当然,我也没办法放弃……

效果图

先看一下最终的效果图,左侧显示了整个D盘的文件系统结构(只包含文件夹),右侧显示左侧点击项的文件结构详情(包括文件夹及文件)。可以看到当我勾选右侧的文件夹,无论左侧对应项,还是右侧的子级文件都进行了相应的联动。

思路及代码

像Windows系统的文件资源管理器,因为涉及的文件结构的复杂和数量之大,像以前操作普通的、简单数据那样,将所有数据加载根本不合适。而这次我写的项目就正好碰到了,只能想办法解决。而要实现此功能难点有

1>数据量大,树形关系过于庞大;

2>点击勾选联动,并且保持左右一致,并且界面数据统一变化;

3>点击过快可能导致冲突,崩溃(此问题跟我的实现方法有很大的关系)。

最终的解决办法:

1>选中项展开时,只显示两层文件:子级项,及孙级项。因为展开选中项时,首先显示的是子级,为了显示子级下是否还有文件夹,能否展开,所以展开两层。

2>为了保持数据的一致,我将存储数据的结构体设置为成员变量,而每一项的数据(data)存储着指向成员变量中与本项相关的结构体;本侧的联动,通过迭代实现;而左右的一致,则是 根据数据的一致性,重新刷新项的勾选状态和项的数据存储。(大概思路这样,详细逻辑更为复杂)

3>由于我每项的数据存储着指向成员变量中与本项相关的结构体,即指向本项数据及其家族数据的结构体,而点击过快时,虽然代码执行完了,但是内部资源可能还在占用,所以可能会出现占用资源的冲突,属于“牵一发动全身”(可能跟电脑的多核有关)。所以就崩了,为了防止操作过快,所以我每次点击后加了一个一秒的动画。

左侧展开

左侧展开比较简单,就是需要判断一下是否需要添加显示项,即判断展开项的孙级是否有添加到界面上,有则返回,没有则添加。

void FileSystemWidget::addChildrenFolderAfterLeftExpend(QTreeWidgetItem *pCurItem)
{
    disconnect(ui->treeWidget, SIGNAL(itemExpanded(QTreeWidgetItem*)), this, SLOT(addChildrenFolderAfterLeftExpend(QTreeWidgetItem*)));
    myWaitDlg.showGif();

    //判断是否需要添加显示项
    bool flag=true;
    for(int i=0;i<pCurItem->childCount();i++)
    {
        QTreeWidgetItem* childItem=pCurItem->child(i);
		QVariant var = childItem->data(0, Qt::UserRole + 1);
        if(var.canConvert<MyFileData*>())
        {
            MyFileData* rootDir=var.value<MyFileData*>();
             if (rootDir->fileordir==SYS_DIRECTORY)
             {//判断是否是文件夹
                 int childCount=childItem->childCount();
                 if(childCount!=0)
                 {
                     flag=true;
                     break;
                 }else{
                     flag=false;
                     break;
                 }
             }
        }
    }
    //添加显示项
    if(!flag)
    {
        for(int i=0;i<pCurItem->childCount();i++)
        {
            QTreeWidgetItem* childItem=pCurItem->child(i);
			bool ischecked;
			QVariant var = childItem->data(0, Qt::UserRole + 1); 
			if (var.canConvert<MyFileData*>())
            {
				MyFileData* page = var.value<MyFileData*>();
				ischecked = page->isChecked;
				childItem->setData(0, Qt::UserRole + 1, QVariant::fromValue(page));
			}
         
  • 1
    点赞
  • 8
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值