QPainter 组合在背景下无法按预期工作
QPainter composition not working as expected with background
我想在白色背景的 QFrame 上绘制两个颜色和透明度相同的矩形。这些矩形应该重叠并且它们的透明度不应该改变(也在重叠区域)。所以像这样:
这是我目前的代码:
class Canvas : public QFrame
{
public:
void paintEvent(QPaintEvent * event) override;
};
void Canvas::paintEvent(QPaintEvent *event)
{
QPainter painter( this );
painter.setPen(QPen(Qt::NoPen));
painter.setBrush(QBrush(QColor(0,0,255,125)));
painter.drawRect(QRect(10,10,100,100));
painter.setCompositionMode(QPainter::CompositionMode_Source);
painter.setBrush(QBrush(QColor(0, 0, 255, 125)));
painter.drawRect(QRect(80, 80, 100, 100));
}
int main( int argc, char **argv )
{
QApplication a( argc, argv );
Canvas canvas;
canvas.setAutoFillBackground(true);
QPalette pal;
pal.setColor(QPalette::Window, QColor(Qt::red));
canvas.setBackgroundRole(QPalette::Window);
canvas.setPalette(pal);
canvas.show();
return a.exec();
}
但是这会产生以下图像:
我已经为画家尝试了所有可能的构图模式,但none似乎给了我想要的效果。我猜 CompositionMode_Source 是正确的,因为如果我使用以下代码:
QPixmap pixmap(200, 200);
pixmap.fill(Qt::transparent);
QPainter painter(&pixmap);
painter.setPen(QPen(Qt::NoPen));
painter.setBrush(QBrush(QColor(0, 0, 255, 125)));
painter.drawRect(QRect(10, 10, 100, 100));
painter.setCompositionMode(QPainter::CompositionMode_Source);
painter.setBrush(QBrush(QColor(0, 0, 255, 125)));
painter.drawRect(QRect(80, 80, 100, 100));
QLabel label;
label.setPixmap(pixmap);
label.show();
我确实得到了想要的效果(但没有红色背景):
但是,如果我将填充更改为 Qt::red,我会再次得到:
我在这里错过了什么?我怎样才能得到我想要的效果?这个的实际应用是我想在 QFrame 派生的 class 上绘制矩形,它是在我有限控制的第三方库中实现的。
我发现代码存在三个问题:
- 第一个矩形是用 alpha 混合(Source Over 模式)绘制的,因为您是在第一次绘制调用之后设置合成模式。第二个改为使用源模式(即按原样复制源像素,不执行 alpha 混合)。
- 确实,Source 不执行您似乎想要的 alpha 混合。所以不要用那个!默认合成模式可以满足您的需求。
- 绘制两个不同的形状将在它们之间进行合成。这显然是预料之中的,因为您正在进行 两次 绘制调用;第二个绘图调用会发现目的地已经被第一个调用改变了。如果你不想这样,你必须找到一种方法在 one 绘制调用中绘制两个形状(例如:将它们都添加到一个 QPainterPath,然后在一次绘制中绘制路径调用),或在稍后阶段执行合成(例如:将它们绘制到不透明的 QImage 上,然后在一次绘制调用中将图像混合到目标位置)。
我想在白色背景的 QFrame 上绘制两个颜色和透明度相同的矩形。这些矩形应该重叠并且它们的透明度不应该改变(也在重叠区域)。所以像这样:
这是我目前的代码:
class Canvas : public QFrame
{
public:
void paintEvent(QPaintEvent * event) override;
};
void Canvas::paintEvent(QPaintEvent *event)
{
QPainter painter( this );
painter.setPen(QPen(Qt::NoPen));
painter.setBrush(QBrush(QColor(0,0,255,125)));
painter.drawRect(QRect(10,10,100,100));
painter.setCompositionMode(QPainter::CompositionMode_Source);
painter.setBrush(QBrush(QColor(0, 0, 255, 125)));
painter.drawRect(QRect(80, 80, 100, 100));
}
int main( int argc, char **argv )
{
QApplication a( argc, argv );
Canvas canvas;
canvas.setAutoFillBackground(true);
QPalette pal;
pal.setColor(QPalette::Window, QColor(Qt::red));
canvas.setBackgroundRole(QPalette::Window);
canvas.setPalette(pal);
canvas.show();
return a.exec();
}
但是这会产生以下图像:
我已经为画家尝试了所有可能的构图模式,但none似乎给了我想要的效果。我猜 CompositionMode_Source 是正确的,因为如果我使用以下代码:
QPixmap pixmap(200, 200);
pixmap.fill(Qt::transparent);
QPainter painter(&pixmap);
painter.setPen(QPen(Qt::NoPen));
painter.setBrush(QBrush(QColor(0, 0, 255, 125)));
painter.drawRect(QRect(10, 10, 100, 100));
painter.setCompositionMode(QPainter::CompositionMode_Source);
painter.setBrush(QBrush(QColor(0, 0, 255, 125)));
painter.drawRect(QRect(80, 80, 100, 100));
QLabel label;
label.setPixmap(pixmap);
label.show();
我确实得到了想要的效果(但没有红色背景):
但是,如果我将填充更改为 Qt::red,我会再次得到:
我在这里错过了什么?我怎样才能得到我想要的效果?这个的实际应用是我想在 QFrame 派生的 class 上绘制矩形,它是在我有限控制的第三方库中实现的。
我发现代码存在三个问题:
- 第一个矩形是用 alpha 混合(Source Over 模式)绘制的,因为您是在第一次绘制调用之后设置合成模式。第二个改为使用源模式(即按原样复制源像素,不执行 alpha 混合)。
- 确实,Source 不执行您似乎想要的 alpha 混合。所以不要用那个!默认合成模式可以满足您的需求。
- 绘制两个不同的形状将在它们之间进行合成。这显然是预料之中的,因为您正在进行 两次 绘制调用;第二个绘图调用会发现目的地已经被第一个调用改变了。如果你不想这样,你必须找到一种方法在 one 绘制调用中绘制两个形状(例如:将它们都添加到一个 QPainterPath,然后在一次绘制中绘制路径调用),或在稍后阶段执行合成(例如:将它们绘制到不透明的 QImage 上,然后在一次绘制调用中将图像混合到目标位置)。