功能:用正常的QCombobox控件,点击下拉出现树节点展示数据.
功能代码:
QTreeView treeView = new QTreeView(this);
QTreeView treeView->setHeaderHidden(true);
QStandardItemModel* model = new QStandardItemModel();
QStandardItem* rootItem = model->invisibleRootItem(); //返回model的不可见根节点
QString sNewTemplatePath= QString("C:\logs\testDir"); //文件夹和文件的路径
QStringList sSuffixList;
sSuffixList << "txt"; //文件后缀
searchSuffixAllFileTree(sNewTemplatePath,sSuffixList,rootItem); //递归遍历路径下文件夹和文件,显示到树上
treeView->setModel(model);
treeView->setEditTriggers(QAbstractItemView::NoEditTriggers);
ui->comboBox->setView(treeView);
ui->comboBox->setModel(model);
treeView->expand(treeView->model()->index(0, 0)); //展开第一级的第一个节点
//递归遍历路径下文件夹和文件函数
void test::searchSuffixAllFileTree(const QString& sDirPath, QStringList& sfileSuffixList, QStandardItem* parentItem)
{
QDir dir(sDirPath);
if (!dir.exists())
return ;
dir.setFilter(QDir::Dirs|QDir::Files|QDir::NoDotAndDotDot);
dir.setSorting(QDir::DirsFirst);
QFileInfoList list;
list = dir.entryInfoList();
if(list.size()<1)
return ;
int i=0;
do
{
QFileInfo fileInfo = list.at(i);
bool bisDir = fileInfo.isDir();
if(bisDir)
{
QString sDirPath = fileInfo.filePath();
QString sDirName = fileInfo.fileName();
QStandardItem* item0 = new QStandardItem(sDirName);
item0->setData(sDirPath,Qt::UserRole);
item0->setFlags(item0->flags() /*& ~Qt::ItemIsEnabled*/ & ~Qt::ItemIsSelectable); //ItemIsEnabled这个不能加,其他参数是不让鼠标选中父节点而收起combobox
parentItem->appendRow(item0); //添加子节点
searchSuffixAllFileTree(fileInfo.filePath(),sfileSuffixList,item0);
}
else
{
QString suffix = fileInfo.suffix();
if(sfileSuffixList.contains(suffix,Qt::CaseInsensitive))
{
QString sFilePath = fileInfo.filePath();
QString sFileName = fileInfo.baseName(); //文件名称不带后缀
QStandardItem* item1 = new QStandardItem(sFileName);
item1->setData(sFilePath,Qt::UserRole);
parentItem->appendRow(item1); //添加子节点
}
}
i++;
}
while(i < list.size());
}
设置完毕后可以通过model的findItems函数搜索子节点是否存在:
QStandardItemModel *model = static_cast<QStandardItemModel*>(m_treeView->model());
QList<QStandardItem*> listItem = model->findItems(m_sSJCJMB,Qt::MatchContains | Qt::MatchRecursive);
/*
1、QList<QStandardItem *> QStandardItemModel::findItems(const QString & text, Qt::MatchFlags flags = Qt::MatchExactly, int column = 0) const
不特殊指定第二个参数的情况下,此函数只会搜索TreeView的顶层元素,不会匹配子元素。
第二个参数中加入“Qt::MatchContains | Qt::MatchRecursive”,则可以完成子元素的匹配。
不过,这个方法尤其局限性,即不能搜索特定角色(DataRole)的数据,而只是匹配DisplayRole的数据
2、virtual QModelIndexList match(const QModelIndex & start, int role, const QVariant & value, int hits = 1, Qt::MatchFlags flags = Qt::MatchFlags( Qt::MatchStartsWith | Qt::MatchWrap )) const
针对特定角色(DataRole)的数据,可以用此函数来解决,用处类似1所说,主要区别在于可以指定要匹配的数据角色(DataRole,第二个参数)
最后一个参数中加入“Qt::MatchContains | Qt::MatchRecursive”,则可以完成子元素的匹配,不加的话也是默认只匹配顶层元素。
*/
遍历treeView的节点,存起来:
QStandardItemModel *model = static_cast<QStandardItemModel*>(ui->treeView->model());
QStandardItem* rootItem = model->invisibleRootItem();
QList<QStandardItem*> listChildItem,listParentItem; //节点存起来
ChildrenItems(rootItem);
void DirTreeView::ChildrenItems(QStandardItem *root_item)
{
if(root_item->hasChildren()) //判断是否存在子节点
{
for(int i = 0;i < root_item->rowCount() ;i++)
{
QStandardItem * item = root_item->child(i);
if(!item->hasChildren()) //没有子节点,表示是最后一级节点
{
listChildItem.append(item);
}
else
{
listParentItem.append(item); //父节点
ChildrenItems(item);
}
}
}
}