我有这样的图像:
我有一个自定义小部件,它重新实现了
paintEvent()
。
在图像的顶部,我想绘制一个覆盖层,并保留一个或多个矩形。具有圆角和适当的抗锯齿功能。
我猜这可能通过 QPainter::CompositionMode 实现。但如何呢?也许将覆盖层绘制到 QImage 中?颠倒过来?
在paint.net中,我在第二层中画了一个矩形,然后用魔术棒选择了内部,并将其删除。我不知道如何用 QPainter 做到这一点。
使用合成模式是可能的,但这需要完全理解它们的行为(坦率地说,我从来无法理解它们)。
此外,在使用像素图时,通常还需要进一步的步骤,即在临时“缓冲区”(另一个 QPixmap 或 QImage)上绘制其中一个图层。
只要“遮罩”很简单,它不涉及多个图像的 Alpha 混合,并且图像是不透明的(根本没有透明度),我们可以遵循更简单的路径,即绘画over并最终通过剪切内容来“清除”所需区域。
程序其实很简单:
setClipPath()
(设置了 Antialiasing
渲染提示);我不会用C++编写,但是下面Python中的简单示例应该足够清楚了:
from PyQt5.QtCore import *
from PyQt5.QtGui import *
from PyQt5.QtWidgets import *
class ClipTest(QWidget):
def __init__(self):
super().__init__()
# This is the original image used in the question
self.pixmap = QPixmap('baseimage.png')
self.setFixedSize(self.pixmap.size())
def paintEvent(self, event):
qp = QPainter(self)
qp.setRenderHint(qp.Antialiasing)
qp.drawPixmap(0, 0, self.pixmap)
# draw the darker "shade" on the whole widget
qp.fillRect(self.rect(), QColor(32, 32, 32, 127))
path = QPainterPath()
# add a couple of rounded rects, which are also colliding
path.addRoundedRect(250, 110, 140, 140, 20, 20)
path.addRoundedRect(380, 110, 140, 140, 20, 20)
# to fill all enclosed regions, including those of colliding
# sub paths that may be otherwise be unpainted
path.setFillRule(Qt.WindingFill)
# clip the painting on the path above
qp.setClipPath(path)
# redraw the pixmap again
qp.drawPixmap(0, 0, self.pixmap)
app = QApplication([])
win = Test()
win.show()
app.exec()
给出以下结果: