Didac Perez Parera
Didac Perez Parera

Reputation: 3814

Qt widget opacity issue

I am trying to capture the mouse over event from a widget which is a subclass of QLabel in which I paint pixmaps. I just need to capture this event for creating a transparency effect by setting the opacity to 50% for example. I have tried with setWindowOpacity(0.5) without success.

So, the question is: how can I modify the opacity of an image that has been painted in a widget that is a subclass of a QLabel?

PaintWidget.cpp

void PaintWidget::paintEvent(QPaintEvent *aEvent)
{
    QLabel::paintEvent(aEvent);

    if (_qpSource.isNull()) //no image was set, don't draw anything
        return;

    float cw = width(), ch = height();
    float pw = _qpCurrent.width(), ph = _qpCurrent.height();

    if (pw > cw && ph > ch && pw/cw > ph/ch || //both width and high are bigger, ratio at high is bigger or
        pw > cw && ph <= ch || //only the width is bigger or
        pw < cw && ph < ch && cw/pw < ch/ph //both width and height is smaller, ratio at width is smaller
        )
        _qpCurrent = _qpSource.scaledToWidth(cw, Qt::FastTransformation);
    else if (pw > cw && ph > ch && pw/cw <= ph/ch || //both width and high are bigger, ratio at width is bigger or
        ph > ch && pw <= cw || //only the height is bigger or
        pw < cw && ph < ch && cw/pw > ch/ph //both width and height is smaller, ratio at height is smaller
        )
        _qpCurrent = _qpSource.scaledToHeight(ch, Qt::FastTransformation);

    int x = (cw - _qpCurrent.width())/2, y = (ch - _qpCurrent.height())/2;

    QPainter paint(this);
    paint.drawPixmap(x, y, _qpCurrent);
}

void PaintWidget::setPixmap(const QPixmap& pixmap)
{
    _qpSource = _qpCurrent = pixmap;
    repaint();
}

Upvotes: 0

Views: 1471

Answers (3)

Didac Perez Parera
Didac Perez Parera

Reputation: 3814

I have finally found the solution. I created a local variable in the class that represents the value of the opacity and I have also created the next method:

void PaintWidget::setOpacity(const double opacity)
{
    this->opacity = opacity;
    repaint();
}

and in the end of the paintEvent method:

    [...]
    QPainter paint(this);
    paint.setOpacity(opacity);
    paint.drawPixmap(x, y, _qpCurrent);
    [...]
}

Upvotes: 1

UmNyobe
UmNyobe

Reputation: 22890

Are you working on Linux or X11 ? Therefore setWindowOpacity(0.5) will work only if your window manager is composite. Furthermore, even if this work correctly you still have troubles. When you are applying the pixmap with

 QPainter paint(this);
 paint.drawPixmap(x, y, _qpCurrent);

the opacity level of the window cannot be magically applied to the pixmap. You need to set either the opacity of the painter, or to use a pixmap which has an alpha channel (which defines transparency).

Upvotes: 2

Nicholas Smith
Nicholas Smith

Reputation: 11754

The reason why setWindowOpacity won't work for you is that you've overridden the paintEvent. There's a lot of code inside of QWidgetPrivate for setting the opacity levels and painting the canvas you can look at, as you've got custom painting occurring you'll need a way of setting the opacity and then calling a repaint.

Upvotes: 0

Related Questions