我们经常看到优酷中会根据每个人的喜好,推荐不同的电影,不同的电视剧等。那么,如果是你在项目中遇到了类似的需求,该如何做呢。
今天,小豆君就给大家推荐一段有意思的代码作为参考。
为了便于说明,就讲一个比较简单的例子,作为引子吧。
制作一个随机颜色生成器,就像下面的这张图那样,每2秒生成100种不同的颜色。
下面是实现细节:
1 generate
在标准库中,有一个叫做generate的函数模板,其声明如下:
template<typename _FIter, typename _Generator> void generate(_FIter, _FIter, _Generator);
FIter是前向迭代器,前两个参数标记了容器的开始和结束,即begin和end
第三个参数_Generator是一个生成器,也可称为函数对象,它是一个实现了运算符小括号"()"的类。
generate函数的作用是为[begin,end)范围指定的每个元素赋值,而这个值都由第三个参数_Generator生成。
2 函数对象
//函数对象,颜色生成器 //它重新实现了operator(),这样就可以当做generate的第三个参数了 class ColorGen { QVector<QColor> used;//标记已经使用过的颜色 ulong limit; //最多可以生成limit个颜色 public: ColorGen(ulong lim) : limit(lim){} QColor operator()() { int sz = used.size(); while (sz < limit) { QColor clr(qrand() % 256, qrand() % 256, qrand() % 256); if (!used.contains(clr)) { used.append(clr); return clr; } } //如果颜色已经完全用完,则将所有颜色清空 used.clear(); return QColor(); } };
使用以上的类,便可以生成一个随机颜色,对于ColorGen实例化的对象c,对它的调用就像是在调用一个函数一样,所以我们将之称为函数对象。
ColorGen c(100); qDebug() << c();//实际上调用的是c.operator();它看起来就像是一个函数一样,但c本身是一个对象
3 创建颜色窗口类
新建一个ColorGenWidget类,继承自QWidget colorgenwidget.h
#ifndef COLORGENWIDGET_H #define COLORGENWIDGET_H #include <QWidget> namespace Ui { class ColorGenWidget; } class ColorGenWidget : public QWidget { Q_OBJECT public: explicit ColorGenWidget(QWidget *parent = 0); ~ColorGenWidget(); private slots: void genLabel(); void resetColor(); private: Ui::ColorGenWidget *ui; QVector<QColor> v; }; #endif // COLORGENWIDGET_H
colorgenwidget.cpp
#include <QTimer> #include <QLabel> #include "colorgen.h" #include "colorgenwidget.h" #include "ui_colorgenwidget.h" ColorGenWidget::ColorGenWidget(QWidget *parent) : QWidget(parent), ui(new Ui::ColorGenWidget) { ui->setupUi(this); //先生成1000个随机颜色,并将这些颜色贴在标签上 v.resize(1000); std::generate(v.begin(), v.end(), ColorGen(v.size())); genLabel(); //使用定时器,每2秒更换一次颜色 QTimer *timer = new QTimer(this); connect(timer, SIGNAL(timeout()), this ,SLOT(resetColor())); timer->start(2000); } ColorGenWidget::~ColorGenWidget() { delete ui; } //生成100个颜色标签 void ColorGenWidget::genLabel() { for(int i = 0; i < 100; ++i) { QLabel* label = new QLabel; ui->gridLayout->addWidget(label, i/10, i%10, 1, 1); } resetColor(); } //重新设置每个label的颜色 void ColorGenWidget::resetColor() { //记录未使用的第一个颜色的索引值 static int start = 0; if (start >= v.size())//如果用完了所有颜色,则重新使用 start = 0; for(int i = 0; i < 100; ++i) { int r = i/10;//行号 int c = i%10;//列号 QLabel* label = dynamic_cast<QLabel*>(ui->gridLayout->itemAtPosition(r, c)->widget()); if (label) { //使用第一个未使用的颜色来设置label的颜色 label->setStyleSheet(QString("QLabel{background-color:%1}").arg(v.at(i+start).name())); } } start += 100; }
最后,我们运行一下程序,程序每隔两秒更换一次100种不同的颜色:
是不是很有意思啊,那么下次老板要求做一个随机推荐功能,就可以使用这样的方法了,做这个的另一个原因是给大家分享一下函数对象和标准库联合使用的用法,希望你有所收获吧。
最后也希望大家多多支持小豆君的创作,关注小豆君的公众号“小豆君Qt分享”,最新文章都会在公众号第一时间发布,或者你有不懂的问题,关注公众号后,可加好友或进Qt群获得答案。