一个随机颜色生成器的制作

简介: 一个随机颜色生成器的制作

我们经常看到优酷中会根据每个人的喜好,推荐不同的电影,不同的电视剧等。那么,如果是你在项目中遇到了类似的需求,该如何做呢。

今天,小豆君就给大家推荐一段有意思的代码作为参考。

为了便于说明,就讲一个比较简单的例子,作为引子吧。

制作一个随机颜色生成器,就像下面的这张图那样,每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群获得答案。

相关文章
|
消息中间件 大数据 Kafka
【Kafka】Kafka 中生产者运行流程
【4月更文挑战第10天】【Kafka】Kafka 中生产者运行流程
|
自然语言处理 算法 测试技术
实测通义灵码:解锁智能编程的钥匙
写了5个小时的文章,认真的把通义灵码从头到尾玩了一遍,整体来说还是很惊喜的,根据此次不完整的测评,我个人感受可以给通义灵码打到 3.5~4 分之间(满分5分),我觉得这也算是一个很中肯的评价了,具体测试的过程都在本文中有详细列出,希望能和大家一起分享一起学习。本文为原创,未经许可请勿搬运。
361898 17
实测通义灵码:解锁智能编程的钥匙
|
自然语言处理 JavaScript 前端开发
谁才是真正的协议之王?fastjson2 vs fury
谁才是真正的协议之王?fastjson2 vs fury
830 1
|
数据可视化 API vr&ar
探索Qt 3D之旅:从基础到实战,打造引人入胜的三维界面与应用
探索Qt 3D之旅:从基础到实战,打造引人入胜的三维界面与应用
2968 3
|
存储 中间件 关系型数据库
数据库切片大对决:ShardingSphere与Mycat技术解析
数据库切片大对决:ShardingSphere与Mycat技术解析
1558 0
|
11月前
|
Linux 数据处理 Python
编译dpdk19.08.2中example时一系列报错解决
编译dpdk19.08.2中example时一系列报错解决
534 4
|
机器学习/深度学习 算法
全连接层那些事(Fully Connected Layer)
全连接层那些事(Fully Connected Layer)
|
存储 SQL 测试技术
图书馆管理系统系统分析与设计(下)
图书馆管理系统系统分析与设计(下)
856 1
|
JavaScript Java Apache
Java--office(word......)在线预览(openoffice+swfTools+FlexPaper)
Java--office(word......)在线预览(openoffice+swfTools+FlexPaper)
1188 0
|
XML 测试技术 程序员
QTest单元测试框架,简单,好用,高效
QTest单元测试框架,简单,好用,高效

热门文章

最新文章