Qtreewidget实现复杂组织树结构
组织任务树构建
要创建上图所示的任务列表,包含四种类型:空的占位项、案件、文件夹、视频任务;可以创建一个基类,如下图所示,任务列表有为了实现四种不同的项,建立一个基类,定义公共的接口;三个不同项继承这个基类;
(1)组织树基类接口定义
#ifndef TREEITEMBASE_H #define TREEITEMBASE_H #include <QWidget> #include<QVariantMap> enum TreeItemType { EmptyItem=-1, TopCase=0, ChildFolder, videoFile }; class TreeItemBase : public QWidget { Q_OBJECT public: TreeItemBase(QWidget *parent = 0); ~TreeItemBase(); virtual void setInfo(QVariantMap info)=0; virtual void SetType(TreeItemType type) = 0;//设置是案件、子文件夹、视频文件 virtual int GetType()=0; virtual bool IsChecked()=0;//是否选中 virtual void SetChecked(bool checked) = 0; virtual void SetFilterHover(QString FilterHover); QVariantMap m_info; TreeItemType m_type = TopCase; QString m_strFilterHover = ""; signals: void ItemCheckChange(int checked); };
#endif // TREEITEMBASE_H
(2)添加空的案件或者子文件夹
先添加一个空的占位符,根据类型是案件还是子文件夹,设置不同的图标,等点击确认按钮后,再删除空的占位符,添加案件和子文件夹,并将案件或者子文件夹的本地路径写入数据库;
QTreeWidgetItem* TreeTaskList::AddEmptyFoldToList(QTreeWidgetItem* parant /*= NULL*/) { QVariantMap iteminfo; iteminfo.insert("type", EmptyItem); if (parant == NULL)//添加案件主节点 { QTreeWidgetItem *topItem = new QTreeWidgetItem(ui.treeWidget); QString strTime = QDateTime::currentDateTime().toString("yyyy-MM-dd hh:mm:ss"); topItem->setText(0,strTime); topItem->setData(0, 256, iteminfo); EmptyTreeItem* pCase = new EmptyTreeItem(); pCase->SetType(EmptyItem); pCase->SetAddType(TopCase); topItem->setSizeHint(0, QSize(256, 40)); ui.treeWidget->setItemWidget(topItem, 0, pCase); ui.treeWidget->insertTopLevelItem(0, topItem); ui.treeWidget->setCurrentItem(topItem); pCase->ui.lineEditName->setFocus(); connect(pCase->ui.pBConFirm, &QPushButton::clicked, this, [=]() { if (pCase->ui.lineEditName->text().trimmed()=="") { signalError(-1, "请输入案件名称"); return; } if (AddFoldToList(pCase->ui.lineEditName->text().trimmed())!=NULL)//添加案件 { ui.treeWidget->takeTopLevelItem(ui.treeWidget->indexOfTopLevelItem(topItem));//删除占位 } }); connect(pCase->ui.pBCancel,&QPushButton::clicked, this, [=]() { ui.treeWidget->takeTopLevelItem(ui.treeWidget->indexOfTopLevelItem(topItem));//删除占位 SlotUpdateTreeListBackground(); }); SlotUpdateTreeListBackground(); return topItem; } else//添加文件夹子节点 { QTreeWidgetItem *itemchildforder = new QTreeWidgetItem(parant); QString strTime = QDateTime::currentDateTime().toString("yyyy-MM-dd hh:mm:ss"); itemchildforder->setText(0, strTime); itemchildforder->setData(0, 256, iteminfo); itemchildforder->setSizeHint(0, QSize(200, 40)); EmptyTreeItem* childfold = new EmptyTreeItem(); childfold->SetType(EmptyItem); childfold->SetAddType(ChildFolder); ui.treeWidget->setItemWidget(itemchildforder, 0, childfold); ui.treeWidget->setCurrentItem(itemchildforder); childfold->ui.lineEditName->setFocus(); connect(childfold->ui.pBConFirm, &QPushButton::clicked, this, [=]() { if (childfold->ui.lineEditName->text().trimmed() == "") { signalError(-1, "请输入子文件夹名称"); return; } if (AddFoldToList(childfold->ui.lineEditName->text().trimmed(), parant) != NULL)//添加案件 { parant->takeChild(parant->indexOfChild(itemchildforder));//删除占位 } }); connect(childfold->ui.pBCancel, &QPushButton::clicked, this, [=]() { parant->takeChild(parant->indexOfChild(itemchildforder));//删除占位 }); return itemchildforder; } return NULL; }
(3)自动遍历子文件夹里面的视频文件和文件夹添加到案件
为了实现循环遍历,需要采用递归算法来实现这个函数;循环遍历子文件夹;
void TreeTaskList::RecursiveInputDirFiles(QString strDir,QTreeWidgetItem* parant ) { QDir dirFile(strDir); QDir dirDir(strDir); if (!dirDir.exists()) { return; } dirFile.setSorting(QDir::Time);//优先显示目录 dirDir.setSorting(QDir::Time); //列出dir(path)目录文件下所有文件和目录信息,存储到file_list容器 QStringList fileNameFilter; //视频格式 fileNameFilter <<"*.mp4"<<"*.avi"<<"*.dav"<<"*.asf"<<"*.wmv"<<"*.mpg"<<"*.ts"<<"*.3g2"<<"*.swf"<<"*.flv"<<"*.m2ts"<<"*.mkv"<<"*.3gp"<<"*.vob"<<"*.rmvb"<<"*.mov"<<"*.webm"<<"*.rm"<<"*.mts"<<"*.mpeg"<<"*.264"<<"*.692"<<"*.800"<<"*.801"<<"*.av"<<"*.avx"<<"*.djl"<<"*.dvr"<<"*.g64"<<"*.h3crd"<<"*.h64"<<"*.h264"<<"*.ifv"<<"*.jmv"<<"*.kyd"<<"*.lvf"<<"*.mpk"<<"*.nsf"<<"*.nv4"<<"*.ps"<<"*.rec"<<"*.sdv"<<"*.sv5"<<"*.swf"<<"*.tm4"<<"*.tp"<<"*.bhd"<<"*.dat"<<"*.h265"<<"*.he4"<<"*.m4c"<<"*.pep"<<"*.smf"<<"*.sv4"<<"*.vdg"<<"*.601"<<"*.452094848"; dirFile.setNameFilters(fileNameFilter); QFileInfoList file_list = dirFile.entryInfoList(QDir::Files | QDir::Hidden | QDir::NoSymLinks); //列出dir(path)目录下所有子文件夹 QFileInfoList folder_list = dirDir.entryInfoList(QDir::Dirs | QDir::Hidden | QDir::NoDotAndDotDot); if (file_list.size() == 0 && folder_list.size() == 0) { return; } //添加视频文件到列表 QString strfilepath = ""; for (int i = 0; i < file_list.size(); i++) { strfilepath = file_list[i].absoluteFilePath(); AddVideoTaskToList(strfilepath, parant); } //进行子文件夹folder_list递归遍历,将内容存入file_list容器 for (int i = 0; i != folder_list.size(); i++) { //添加子文件夹 QString strDirName = folder_list.at(i).fileName(); if (strDirName=="temp")//自动过滤掉临时文件夹 { continue; } QTreeWidgetItem* childFold = AddFoldToList(strDirName,parant); //递归子文件夹 if (childFold!=NULL) { RecursiveInputDirFiles(folder_list.at(i).absoluteFilePath(), childFold); } } }
自己开发了一个股票智能分析软件,功能很强大,需要的关注微信公众号:QStockView