02 从QLabel聊起:自定义控件扩展-图片控件

系列文章目录

01 Qt自定义风格控件的基本原则-CSDN博客

目录

系列文章目录

前言

一、使用场景

二、实现思路

1. 概述

2.功能接口

3. 绘制代码示例

总结


前言

如果让我选一个极其鸡肋的Qt原生控件,我一定会投票给QLabel类!

首先,就其功能而言,我觉得QLabel类的功能相对冗杂!对于QLabel的定位是既可以用于展示文本,也可以用于展示图片。

然而,对于展示文本的场合,却不支持长文本省略模式(就是单行文字过长时,显示...)

对于展示图片的场合, 却又不支持svg格式图片的展示!我们知道如果用QLabel展示png图片,那么任意放缩的场景下,必然会出现图片模糊的情形!所以,我也推荐大伙如果可以的话,最好使用svg格式的资源文件!

另外,如果大伙儿了解qml模块就会知道,它的基本组件并不是Label组件,反而是有两个名为Image和Text的组件, 我认为这两个组件的存在何尝不是对QLabel组件的功能拆解与扩展呢?

所以, 本篇介绍的是QWidget自定义扩展组件-Image组件

一、使用场景

场景很简单,就是单纯用于展示一张静态图的场合, 比如:头像、Logo

02 从QLabel聊起:自定义控件扩展-图片控件_第1张图片 图1-1

二、实现思路

1. 概述

继承基类QWidget, 在paintEvent中根据填充模式绘制目标图片 

2.功能接口

代码如下(示例):

    enum FillMode
    {
        Stretch = 0,    //忽略宽高比,水平、垂直方向上拉伸效果=》拉伸铺满
        PreserveAspectFit,//保持宽高比铺满效果
        PreserveAspectCrop,//保持宽高比裁切铺满效果
        Tile,              //水平、垂直方向层叠效果
        TileVertically,//水平方向铺满、垂直方向层叠效果
        TileHorizontally,//垂直方向铺满、水平方向层叠效果
        Pad             //不添加任何变换,居中显示
    };
//设置图片资源路径:支持svg格式及其他png等基本格式
    //暂不支持异步加载网络资源
    void setSource(const QString& src);
    //设置图片填充模式
    void setFillMode(FillMode mode);
    //图片圆角弧度
    void setImageRadius(int radius);


3. 绘制代码示例

void renderSvgPixmap(QPainter* painter)
{
    QRect rcFrame = contentsRect();
    QSvgRenderer svgRender(m_imgSrc);
    if (!svgRender.isValid())
    {
        qDebug() << "invalid svg image!";
        return;
    }
    QSize sz = svgRender.defaultSize();
    double dFrameRatio = rcFrame.width()*1.0 / qMax(1, rcFrame.height());
    double dImgRatio = sz.width()*1.0 / qMax(1, sz.height());
    //接近为0, 不绘制内容
    if (qAbs(dImgRatio) <= 0.001 || qAbs(dFrameRatio) <= 0.001)
        return;
    QRect rcRender = rcFrame;
    switch (m_eFillMode)
    {
    case QUiImage::Stretch:
        svgRender.render(painter, rcRender);
        break;
    case QUiImage::PreserveAspectFit:
    {
        if (dFrameRatio > dImgRatio)//基于高度计算宽度
        {
            int iCanvaW = rcFrame.height()* dImgRatio;
            int iCanvaH = rcFrame.height();
            rcRender = QRect( (rcFrame.width() - iCanvaW)*0.5
                , (rcFrame.height() - iCanvaH)*0.5
                , iCanvaW
                , iCanvaH);
        }
        else//基于宽度计算高度
        {
            int iCanvaW = rcFrame.width();
            int iCanvaH = rcFrame.width()/ dImgRatio;
            rcRender = QRect((rcFrame.width() - iCanvaW)*0.5
                , (rcFrame.height() - iCanvaH)*0.5
                , iCanvaW
                , iCanvaH);
        }
        svgRender.render(painter, rcRender);
    }
    break;
    

这里有几个细节,可以强调一下,大伙儿不要再次踩坑了:

  • 绘制区域我们用QWidget::contentsRect接口, 这样的话不会影响QWidget的margin属性展示
  • 因为涉及到svg图片的展示,所以要用到svg模块。 值得一说的是,千万不要把svg资源绘制到一张QPixmap上,然后把QPixmap放缩、绘制到QWidget上!因为这样放缩QPixmap并展示依旧会模糊!

三、总结

以上就是今天要讲的内容,本文主要为针对QLabel图片功能接口的拆分与扩展,然后独立出一个自定义的组件功能类Image。

既聊思路,也说代码!我们下次继续分享自定义风格扩展组件!

你可能感兴趣的:(Qt-GUI:自定义组件的思路,qt)