QT中setMask在QBitmap覆盖整个Widget时失效如何解决?
问题:QBitmap设置全Widget遮罩时setMask失效
当使用QRect(0, 0, ui->widget->width(), ui->widget->height())填充QBitmap作为遮罩时,setMask功能失效,相关代码如下:
QBitmap windowMask(ui->widget->width(), ui->widget->height()); windowMask.fill(Qt::transparent); QPainter p(&windowMask); p.fillRect(QRectF(0, 0, ui->widget->width(), ui->widget->height()), Qt::white); p.end(); ui->widget->setMask(windowMask);
此时遮罩无法生效,达不到预期效果。
但将填充区域改为QRectF(1, 1, ui->widget->width(), ui->widget->height())时,setMask功能正常,代码示例:
p.fillRect(QRectF(1, 1, ui->widget->width(), ui->widget->height()), Qt::white);
请问如何实现用QBitmap覆盖整个Widget的遮罩效果?
解决方案
原因分析
这种情况是Qt对QBitmap遮罩的处理逻辑导致的:setMask以白色区域为可见区、透明(黑色)区域为隐藏区。如果QBitmap完全填充为白色,相当于没有任何隐藏区域,效果和调用clearMask()一致,所以看起来“失效”;而偏移1像素后,Bitmap边缘存在透明区域,Qt会识别这是有效遮罩,因此功能正常。
实现方式
方式1:用QRegion替代QBitmap(推荐)
如果只是要设置整个Widget为可见区域,直接使用QRegion更简洁,无边界问题:
ui->widget->setMask(QRegion(ui->widget->rect()));
方式2:调整QBitmap的绘制逻辑(必须用QBitmap时)
通过微小调整让Qt识别到有效遮罩,同时视觉上覆盖整个Widget:
QBitmap windowMask(ui->widget->width(), ui->widget->height()); windowMask.fill(Qt::transparent); QPainter p(&windowMask); // 填充内部区域,同时绘制白色边框覆盖边缘透明区 p.fillRect(QRectF(1, 1, ui->widget->width()-2, ui->widget->height()-2), Qt::white); p.setPen(Qt::white); p.drawRect(QRectF(0, 0, ui->widget->width()-1, ui->widget->height()-1)); p.end(); ui->widget->setMask(windowMask);
或者直接创建全白QBitmap,绕开绘制边界问题:
QImage img(ui->widget->width(), ui->widget->height(), QImage::Format_Mono); img.fill(0xff); // 填充全白 QBitmap windowMask = QBitmap::fromImage(img); ui->widget->setMask(windowMask);
内容的提问来源于stack exchange,提问作者Robin L
相关产品推荐
相关产品推荐

