利用C++11的function和bind功能,实现QStandardItemModel的通用遍历函数
扫描二维码
随时随地手机看文章
在使用Qt的树形视图和表格视图QTableView和QTreeView时,经常需要遍历所有条目,每种功能都写一个遍历函数既麻烦又不符合编程最简原则,因此,写一个通用的遍历函数是很必要的(类似于std::for_each),对于遍历时实现的功能不一样,可以通过函数指针来代替需要实现的功能。
在讲这个之前,需要了解std::function和std::bind,具体可以自行谷歌。
可参考:http://blog.csdn.net/qq575787460/article/details/8531397
由于这个遍历函数可能经常用到,因此可以写一个类的静态函数或者是全局函数。
下面把这个功能封装在一个类里
类的头文件如下:
#include#includeclass QStandardItemModelEx { public: QStandardItemModelEx(){} ~QStandardItemModelEx(){} /// /// brief callback_ergodicFun_ptr 回调函数指针,bool f(QStandardItem*),bool用于决定是否继续,如果为true就继续递归,如果为false就停止递归 /// typedef std::functioncallback_ergodicFun_ptr; //typedef void(*callback_ergodicFun_ptr)(QStandardItem*); static void ergodicAllItem(QStandardItemModel* model,callback_ergodicFun_ptr pFun); static bool ergodicItem(QStandardItem* item,callback_ergodicFun_ptr pFun); private: };
这里使用C++11的新特性function(环境 VS2010),定义一个函数指针用于回调实现功能。
函数ergodicAllItem用于遍历所有项目,ergodicItem用于遍历项目下的所有子项目。回调函数返回bool用于决定是否继续,如果为true就继续遍历,如果为false就停止遍历
为了简单起见,下面用递归实现遍历(ergodicItem是尾递归函数)
void QStandardItemModelEx::ergodicAllItem(QStandardItemModel* model,callback_ergodicFun_ptr pFun) { int rows = model->rowCount(); int column = model->columnCount(); for (int i=0;i<rows;++i) { for(int j=0;jitem(i,j); if (item) { if(!ergodicItem(item,pFun)) return; } } } } bool QStandardItemModelEx::ergodicItem(QStandardItem* item,callback_ergodicFun_ptr pFun) { int rows = item->rowCount(); int column = item->columnCount(); for (int i=0;i<rows;++i) { for(int j=0;jchild(i,j); if (childItem) { if(!ergodicItem(childItem,pFun)) return false; } } } return pFun(item); }
用这两个函数就可以遍历所有的项目了,而遍历时需要的动作,就通过回调函数实现。
回调函数即可写在类里,也可以写为全局函数,若除了QStandardItem*还需要别的参数,那么可以用std::bind帮忙。
下面举一个例子
例子功能是通过关键字高亮条目。在使用QTreeView或QTableView时,在条目多的情况下,需要搜索某些条目,对搜索结果进行高亮,这时,就需要遍历整个View里的条目,对符合的条目进行高亮
遍历的函数已经写好,现在缺少的是回调的函数,由于遍历的函数使用的函数指针是std::function,因此回调函数即可写为全局函数也可以写为类成员函数
回调函数声明:
bool callback_hightLightItem(QStandardItem* item,const QStringList keys);
回调函数实现:
bool callback_hightLightItem(QStandardItem* item,const QStringList keys) { QString str = item->text(); if (is_match_string(str,keys)) { item->setData(QVariant(QColor(237,100,100,180)),Qt::BackgroundRole); } else { item->setData(QVariant(),Qt::BackgroundRole); } return true; }
使用QStandardItem的setData函数,设置角色为Qt::BackgroundRole,即可设置背景颜色。
实现函数中is_match_string函数是用来检测是否符合关键字,如果符合关键字,就返回true,符合关键字就给条目背景赋予不同的颜色,否则就把颜色消除。
回调函数返回true,意味着一直遍历,直到所有遍历完成。
通过按钮pushButton_search来触发搜索功能。pushButton_search函数的槽如下:void MainWindow::on_pushButton_search_clicked()
{
QString str = ui->lineEdit_search->text();//获取关键字
if (str.isEmpty())
return;
QStringList keyWords = str.split(QString(" "));
StandardItemModel::ergodicAllItem(
qobject_cast