QT实现背景图片多种填充方式:居中、平铺、缩放、拉伸

        最近用QT开发一个软件,遇到一些问题在网上找不到完善的解决方案,自己做了一些尝试后最后找到符合自己需要的,还有对一些问题的理解,在此做一些记录。不一定是很有效率的通用解决方案,希望遇到相关问题的可以在这里找到一些思路。

        先记录下刚刚做完的窗口背景设置,我需要的是:在没有选择图片的时候,显示背景颜色,而在有图片的时候显示图片,并且图片要可以选择:“居中”、”平铺”、”缩放”、”拉伸”四种填充方式。图片示例如下:

① 图片小于widget情况,从左到右依次为:没有图片、“居中”、“平铺”、“缩放”、“拉伸”

    

① 图片大于widget情况,从左到右依次为:没有图片、“居中”、“平铺”、“缩放”、“拉伸”

    

        在网上查,基本上都在说明QT设置背景颜色、图片的三种方式:setStyleSheet、QPalette、paintEvent。在这里我不作过多用法说明,而针对我的需求,说下这几种方法:

1、使用setStyleSheet

         背景颜色和背景图片可以同时设置(background-color、background-image),存在以下行为:图片路径无法正确解析时,只显示背景颜色;图片可以解析时,按设置方式显示图片,而在图片范围外显示背景颜色。默认的图片显示位置为左上角,填充方式是平铺。这两个可以通过background-position、background-repeat来调整。

        存在问题:这种方式设置的图片都是按原图大小进行显示,不能进行缩放。而且url只能填入路径,不能是一个QPixmap,所以也无法通过调整图片大小来缩放显示。所以只能实现“居中”、”平铺”两种形式,而无法实现“缩放”、“拉伸”

        一种替代方式是使用border-image属性,这种方法显示的图片就是图片调整到widget大小再显示,实现”拉伸”形式。同样无法实现缩放。这种方法不够灵活。

2、使用画板QPalette

        这种方式是通过给QPalette设置QBrush画刷来设置背景的,最有用的地方在于它可以设置QPixmap,使得背景图片可以按照我们想要的大小进行变化,可以轻松实现”拉伸”方式。

        存在问题:这种方法会以平铺的方式填充满整个widget,即使你把图片scale到自己想到的大小,剩余的地方也会被填充。所以这种方式只能实现“平铺”、“拉伸”,而无法实现“居中”、“缩放”。

3、重写paintEvent方法

         这种方法是最灵活的,可以按照自己想要的任何方式描绘背景。可以实现“居中”、“平铺”、“缩放”、“拉伸”。

        存在问题:因为背景如何显示全部要自己手动实现,需要精确的坐标计算图片的显示位置。特别是“平铺”方式,需要根据widget大小和图片的大小先判断出要重复画多少次图,还要计算每一次图的起点。

 

★★★★★

        如果是QLabel这种可以直接设置QPixmap的,就可以比较简单地实现常用的背景图片四种显示方式。而对于不能设置QPixmap的widget,在允许的情况下可以重载该widget,并在该widget内创建一个与widget同样大小的QLabel,专门用来显示背景。在我的项目中,因为要调整的widget是自己实现的,所以最终采用了在内部创建一个QLabel专门处理背景显示问题。

         相关的设置代码如下:

QLabel label = new QLabel(this);
label.setGeometry(0, 0, this->width(), this->height());

QPixmap bgImage("1.jpg");

if (bgImage.isNull())
{
    label->setStyleSheet("background-color:black");
}
else
{
    switch (方式)
    {
        case 居中:
            label->setStyleSheet("background-color:black;background-image:url(1.jpg);background-position:center;background-repeat:no-repeat;");
            break;

        case 缩放:
            label->setStyleSheet("background-color:black");
            label->setAlignment(Qt::AlignCenter);
            label->setPixmap(bgImage.scaled(this->size(), Qt::KeepAspectRatio, Qt::SmoothTransformation));
            break;

        case 拉伸:
            label->setStyleSheet("background-color:black");
            label->setPixmap(bgImage.scaled(this->size(), Qt::IgnoreAspectRatio, Qt::SmoothTransformation));
            break;
            
        case 平铺:
            label->setStyleSheet("background-color:black;background-image:url(1.jpg);background-position:top left;background-repeat:repeat-xy;");
            break;
    }
}

 

  • 32
    点赞
  • 149
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值