QWidget的windowOpacity属性
windowOpacity可以设置透明度。
API | 说明 |
---|---|
windowOpacity() | 获取到控件的不透明数值. 返回 float, 取值为 0.0 -> 1.0 其中 0.0 表⽰全透明, 1.0 表⽰完全不透明. |
setWindowOpacity(flo at n) | 设置控件的不透明数值. |
例子:调整窗口透明度
#include "widget.h"
#include "ui_widget.h"
#include<QDebug>
Widget::Widget(QWidget *parent)
: QWidget(parent)
, ui(new Ui::Widget)
{
ui->setupUi(this);
}
Widget::~Widget()
{
delete ui;
}
//增加不透明度
void Widget::on_pushButton_add_clicked()
{
float opacity = this->windowOpacity();
if(opacity >= 1)
{
return;
}
opacity += 0.1;
qDebug() << opacity;
this->setWindowOpacity(opacity);
}
//减小不透明度
void Widget::on_pushButton_sub_clicked()
{
float opacity = this->windowOpacity();
if(opacity <= 0)
{
return;
}
opacity -= 0.1;
qDebug() << opacity;
this->setWindowOpacity(opacity);
}
上述代码中出现俩个问题:
问题1
窗口的不透明度的变化并不是精确的?
在学习C/C++编程语言中:
关于数据在内存中的存储有俩种情况
(1)整数在内存中的存储(源码、反码、补码、字节序)
(2)浮点数在内存中的存储
其中IEEE 754标准规定了浮点数要使用二进制科学计数法的方式来表示:
把一个浮点数分成了三个部分
(1)符号位
(2)有效数字
(3)指数部分
在进行使用二进制表示有效数字的时候,这里是指小于0的小数部分(默认整数部分是1)
第一个有效数字位表示0.5
第二个有效数字位表示0.25
第三个有效数字位表示0.125
...
例如二进制数字101表示0.625
而像0.1这样的小数,由于float和double有效数字部分长度都是有限的,导致无法凑出一个非常接近0.1这样的数字。
很多编程语言,例如C/C++、Java、python、Go都是使用的这套体系。
其优点是:运算速度快,占用空间小(CPU制造的hi和针对这种运算专门进行优化)
其缺点是:对于有些小数是无法精准表示的。
例如:在使用浮点数进行比较的时候,不能直接使用==进行比较!
0.1 + 0.2 == 0.3 (false)
需要做差,判定差的绝对值小于预期误差范围。
第二个问题
上述代码中,在进行设置之前先判定了opacity的范围,然后再决定是否要设置。
这个设置可以不写,但是为什么我们仍然要写?
这里加了判定条件,但是实际上如果不加这个判定条件,代码也是没有问题的。
超过1.0的数字设置不进去,(setWindowOpacity)其内部也对其进行了判定。
但是还是推荐进行判定!!!
再《代码大全中》进行了详细的讨论:“防御性编程”
在写代码的时候,往往是要把一个大项目划分成几个部分/模块,由几个不同的人负责完成,模块之间要进行交互,往往模块A提供了API(函数,类)给模块B调用。
当在使用别人提供的API来进行调用的时候,是否需要对传入的参数进行检查呢?
例如:当传入一个实参,调用者不知道这个参数是否是一个NULL指针?这个实参是否在调用之前进行了判定?
Test * t = ...
if(t != nullptr)
{
func(t);
{
还是
Test* t = ....
func(t);
void func(Test* t)
{
if(t == nullptr)
{
return;
}
....
}
这俩种判空会选择哪种呢?
在《代码大全》给出了结论,要进行双重判定(double check)
【注意】函数的定义和调用是俩个模块,由俩部分人组成,如果采用double check这种方式,意味着任何一方出错,都不会产生严重后果。