QT中使用图标字体

下面这些QLabel里面都是用的图标字体,这些各种图标本质上都是某一种字体里的某一个字符。

为什么需要图标字体

没有图标字体时,控件设置背景图片需要使用PNG或者SVG的图片。此时就需要准备图片文件,然后添加为资源文件。

然而:

1.正常状态、按下状态、悬浮状态,通常需要修改图片的颜色

2.比如换肤,也需要修改图片的颜色

就导致一个样式的图片,需要准备几张,很繁琐。

有了图标字体库,就可以直接将图标对应的编码,使用setText()方法作为文本设置给控件就可

可以随意设置文本的大小和颜色,达到多种图片的效果

常用的图标字体库

这里以阿里的iconfont为例

官网:https://www.iconfont.cn/

进入之后找到图标库,点进去随便找几个图标:

然后把图标添加进入购物车:

点击购物车:

添加项目:

添加完成后自动进入页面:

重点说一下unicode编码,都是16进制的,我们通常把每一个图标的unicode设置为连续的,方便后续使用。

比如此处是天气类图标那么我们可以把他的Unicode设置为0x0000~0x00FF之间,

后续新增其他图标,比如水果类的图标我们可以设置为0x0100~0x01FF之间,以此类推。

然后点击下载

解压文件,里面的ttf格式文件就是我们需要的,后续需要把他当做资源文件添加进qt项目中:

然后我们打开demo_index.html文件获取字体名称和每个图标的编码,后续要用这些字体图标都需要这两个信息,字体名称一定不能弄错,否则显示出来的图标字体就会乱码:

使用图标字体

1.首先,把ttf文件拷贝到qt项目的路径下,然后以资源文件的形式添加到我们的qt项目中

2.然后我们把对图标字体的使用封装成一个单例类,在qt项目中我们可以通过这个单例类来使用图标字体

#ifndef ICONHELPER_H
#define ICONHELPER_H

#include<QObject>
#include<mutex>
#include<QFontDatabase>
#include<QDebug>
#include<QLabel>
#include<QPushButton>
#include<QPainter>

#define FONT_ALIBABA "iconfont"//图标字体的名称,这里一定要得到图标字体文件里面正确的字体名称否则会乱码
#define FONT_ALIBABA_PATH ":/res/iconfont.ttf"//资源文件的路径,直接右键对应资源文件然后CopyPath

//后续还有其他图标字体,同样这样做,
//先添加资源文件,然后得到其字体名和路径,定义在这儿





//这里懒得分文件写了,实现直接写在hpp文件中
class IconHelper:public QObject
{
    Q_OBJECT

private:
    inline static IconHelper* self=nullptr;//c++17:静态成员前面加inline关键字后可以直接在类里面初始化

    QFont m_font_alibaba;
    //后续有其他图标字体族加进来,同样在这儿新加一个字体变量: QFont m_font_b;

public:
    static IconHelper* Instance()
    {
        static std::once_flag once;
        std::call_once(once,[&](){self=new IconHelper;});

        return self;
    }

    //这个函数存在的意义是方便我们以数组下标的形式来得到图标字体中的每一个图标的Unicode
    //当然,不用也行,知道图标的unicode就行
    QVector<int> getIconOfAlibaba()
    {
        QVector<int> icons;
        //之前设置好的连续的字体图标的编码到这里方便我们写for循环
        for(int i=0xe8c4;i<=0xe8de;++i)
        {
            icons.push_back(i);
        }

        return icons;
    }

    //给标签设置图标
    //参数1:标签的地址
    //参数2:字体族的名称
    //参数3:图标的unicode
    //参数4:图标的大小(粗细)
    void setIcon(QLabel* label,const QString& font_family,int icon_code,int size=10)
    {
        if(font_family==FONT_ALIBABA)
        {
            m_font_alibaba.setPixelSize(size);//设置图标粗细
            label->setFont(m_font_alibaba);//把这个字体设置给标签
            label->setText(QChar(icon_code));//把图标转成QChar类型后通过文本设置给Label
        }
        // else if(font_family==FONT_B)//后续新加字体族
        // {
        //     m_font_alibaba.setPixelSize(size);
        //     label->setFont(m_font_b);
        //     label->setText(QChar(icon_code));
        // }
    }

    //给按钮设置图标
    void setIcon(QPushButton* btn,const QString& font_family,int icon_code,int size=10)
    {
        if(font_family==FONT_ALIBABA)
        {
            m_font_alibaba.setPixelSize(size);//设置图标粗细
            btn->setFont(m_font_alibaba);//把这个字体设置给标签
            btn->setText(QChar(icon_code));//把图标转成QChar类型后通过文本设置给Label
        }
    }


    //这个方法可以根据给定的图标字体,生成一个QPixmap图片,很多地方都会用到QPixmap
    QPixmap getPixmap(const QColor& color,
                      const QString& font_family,
                      int icon_code,
                      int size=10,
                      int width=12,
                      int height=12)
    {
        QFont font;
        if(font_family==FONT_ALIBABA)
        {
            font=m_font_alibaba;
        }
        // else if(font_family==FONT_B)
        // {
        //     font=m_font_b;
        // }


        //把图片绘制到图片上
        QPixmap pic(width,height);//图片的宽高
        pic.fill(Qt::transparent);//图片背景色,这里选择透明

        //使用QPainter进行绘制
        QPainter painter;
        painter.begin(&pic);//在哪里画,在pic里面画
        painter.setRenderHints(QPainter::Antialiasing|QPainter::TextAntialiasing);//设置抗锯齿,使画出来的图片流畅
        painter.setPen(color);//设置笔和笔的颜色

        font.setPixelSize(size);//设置字体的粗细
        painter.setFont(font);//设置笔的字体

        //绘制文本,画在pic的框里面,居中,文本是传进来的图标字体的编码,要转成QChar
        painter.drawText(pic.rect(),Qt::AlignCenter,(QChar)icon_code);
        painter.end();

        return pic;
    }


private:

    IconHelper(const IconHelper& helper)=delete;

    explicit IconHelper(QObject* object=nullptr):QObject{object}
    {

        //1.首先在构造函数中要把这个图标字体加入到我们的系统字体中
        //使用这个类来完成这件事QFontDatabase
        QFontDatabase font_db;
        int font_id;

        //添加iconfont到系统字体中
        if(!font_db.families().contains(FONT_ALIBABA))
        {
            //系统没有iconfont这个字体那么我们就把他添加进去
            font_id=font_db.addApplicationFont(FONT_ALIBABA_PATH);//图标字体资源文件的路径

            //添加完成后判断一下是否添加成功了
            auto font_families=font_db.applicationFontFamilies(font_id);
            if(font_families.count()>0)
            {
                //大于0则证明添加进去了
                //2.获取该字体
                m_font_alibaba=QFont(FONT_ALIBABA);

                //如果可能的话,在渲染文本时不要提示字形的轮廓。文本布局将是排版准确和可扩展的,使用与打印时相同的指标
                m_font_alibaba.setHintingPreference(QFont::PreferNoHinting);
            }

        }


        //继续添加图标字体族B到体统字体中,
        //代码和上面一样只不过图标字体名和资源路径,以及获取到的字体不同

        //我们可以在控制台进行打印当前系统支持的各种字体,看新加的字体是否加了进来
        // foreach (QString font_family, font_db.families()) {
        //     qDebug()<<font_family;//打印当前支持的字体族的名称
        //     foreach (QString style, font_db.styles(font_family)) {
        //         QString str_size;
        //         foreach (int size, font_db.smoothSizes(font_family,style)) {
        //             str_size+=QString::number(size)+=" ";
        //         }

        //         //打印该字体族支持的样式,以及每种样式支持的粗细
        //         qDebug()<<"\t"<<style<<"\t"<<str_size;
        //     }
        // }

    }

};


#endif // ICONHELPER_H

3.然后我们就可以直接调用这个单例类的setIcon方法来给控件设置图标了!

上面的hpp文件可以直接拷贝后添加到qt项目中进行使用

总结下来就是:

1.把图标字体的ttf文件添加到qt资源文件中

2.通过QFontDatabase类将图标字体族添加到系统字体中

3.通过QFont和图标字体族名称来构造该图标字体族

4.将该QFont设置给控件

5.利用控件的setText函数以及图标的unicode(需要转成QChar类型),将字体图标设置给控件

可以下载demo试一试,也可以进行改造丰富。

  • 4
    点赞
  • 12
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值