QPainter组合不能按预期工作与背景

时间:2016-04-26 10:35:04

标签: c++ qt alphablending qpainter

我正在尝试在具有白色背景的QFrame上绘制两个具有相同颜色和透明度的矩形。这些矩形应该重叠,它们的透明度不应该改变(也在重叠区域)。像这样:

enter image description here

这是我到目前为止的代码:

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();
}

然而,这会产生以下图像:

enter image description here

我已经为画家尝试了所有可能的构图模式,但似乎都没有给我预期的效果。我猜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();

我确实得到了预期的效果(但没有红色背景):

enter image description here

但是,如果我将填充更改为Qt :: red,我会再次:

enter image description here

我在这里缺少什么?我怎样才能达到理想的效果?实际的应用是我想在QFrame派生类上绘制矩形,该类在我受限制的第三方lib中实现。

1 个答案:

答案 0 :(得分:4)

我发现代码有三个问题:

  1. 第一个矩形是使用 alpha混合(Source Over模式)绘制的,因为您在第一次绘制调用后设置了合成模式。第二个使用源模式(即按原样复制源像素,不执行alpha混合)。
  2. 确实Source不会执行您想要的Alpha混合。所以不要使用它!默认的合成模式可以满足您的需求。
  3. 绘制两种不同的形状将在它们之间执行合成。这显然是预期的,因为你正在进行两次绘制调用;第二个绘制调用将找到第一个已更改的目标。如果你不想这样,你必须找到一种方法在一个绘制调用中绘制两个形状(例如:将它们都添加到一个QPainterPath,然后在一个绘制调用中绘制路径),或者在稍后阶段执行合成(例如:将它们绘制到不透明的QImage上,然后在一次绘制调用中将图像混合到目标上)。