Skip to content
  • Categories
  • Recent
  • Tags
  • Popular
  • Users
  • Groups
  • Search
  • Get Qt Extensions
  • Unsolved
Collapse
Brand Logo
  1. Home
  2. Qt Development
  3. General and Desktop
  4. Creating a dark overlay to apply on top of other widgets
QtWS25 Last Chance

Creating a dark overlay to apply on top of other widgets

Scheduled Pinned Locked Moved Unsolved General and Desktop
overlayqgraphicsopacitqpropertyanimat
2 Posts 1 Posters 970 Views
  • Oldest to Newest
  • Newest to Oldest
  • Most Votes
Reply
  • Reply as topic
Log in to reply
This topic has been deleted. Only users with topic management privileges can see it.
  • S Offline
    S Offline
    saeid0034
    wrote on 9 Mar 2022, 13:24 last edited by
    #1

    Hi, I want to be able to create a dark overlay on top of other widgets that can be turned on or of with animation, so for I have this

    OverlayWidget.h

    #pragma once
    
    #include <QObject>
    #include <QFrame>
    #include <QGraphicsOpacityEffect>
    #include <QPropertyAnimation>
    #include <QPaintEvent>
    #include <QMouseEvent>
    
    class OverlayWidget : public QWidget
    {
        Q_OBJECT
    public:
        explicit OverlayWidget(QWidget* parent = nullptr, const int duration = 370);
        void show(const bool& show = true);
    
    signals:
        void pressed(); // used for close the overlay when its opened and user click on it
    
    private:
        QGraphicsOpacityEffect fade_effect;
        QPropertyAnimation animation;
    
    protected:
        void mousePressEvent(QMouseEvent* event);
        void paintEvent(QPaintEvent* event);
        bool eventFilter(QObject* obj, QEvent* ev) override;
        bool event(QEvent* ev) override;
    
    private:
        void newParent();
    };
    

    OverlayWidget.cpp

    #include "Overlay.h"
    #include <QPainter>
    #include <QDebug>
    
    OverlayWidget::OverlayWidget(QWidget* parent, const int duration)
        : QWidget{ parent }
        , fade_effect(this)
        , animation(&fade_effect, "opacity")
    {
        setPalette(Qt::transparent);
        setAttribute(Qt::WA_NoSystemBackground);
        newParent();
        // setStyleSheet("border-radius:8;");
        setGraphicsEffect(&fade_effect);
        animation.setStartValue(0.0);
        animation.setEndValue(1.0);
        animation.setEasingCurve(QEasingCurve::InOutQuint);
        animation.setDuration(duration);
        setVisible(false);
        setEnabled(false);
    }
    
    void OverlayWidget::newParent()
    {
        if (!parent()) return;
        parent()->installEventFilter(this);
        raise();
    }
    
    bool OverlayWidget::eventFilter(QObject* obj, QEvent* ev)
    {
        if (obj == parent()) {
            if (ev->type() == QEvent::Resize)
                resize(static_cast<QResizeEvent*>(ev)->size());
            else if (ev->type() == QEvent::ChildAdded)
                raise();
        }
        return QWidget::eventFilter(obj, ev);
    }
    
    bool OverlayWidget::event(QEvent* ev)
    {
        if (ev->type() == QEvent::ParentAboutToChange) {
            if (parent()) parent()->removeEventFilter(this);
        }
        else if (ev->type() == QEvent::ParentChange)
            newParent();
        return QWidget::event(ev);
    }
    
    void OverlayWidget::show(const bool& show)
    {
        animation.stop();
        animation.setStartValue(animation.currentValue());
        animation.setEndValue(show ? 1.0 : 0.0); // show or hide
        animation.start();
        if (show) {
            setVisible(true);
            setEnabled(true);
            setAttribute(Qt::WA_TransparentForMouseEvents, false);
        }
        else {
            // setVisible(false);
            setEnabled(false);
            setAttribute(Qt::WA_TransparentForMouseEvents);
        }
    }
    
    void OverlayWidget::paintEvent(QPaintEvent* event)
    {
        Q_UNUSED(event);
    
        QPainter painter(this);
        painter.setRenderHint(QPainter::Antialiasing);
        painter.setBrush(QBrush(QColor(0, 0, 0, 150)));
        painter.setOpacity(50);
        painter.setPen(Qt::NoPen);
        painter.drawRoundedRect(rect(), 8.0, 8.0); // becasue my frame is round
    }
    
    void OverlayWidget::mousePressEvent(QMouseEvent* event)
    {
        if (event->button() == Qt::LeftButton)
            emit pressed();
    }
    

    so far its work, but I think Im doing it very bad... any suggestion on how to improve it?

    1 Reply Last reply
    0
    • S Offline
      S Offline
      saeid0034
      wrote on 10 Mar 2022, 11:41 last edited by
      #2

      Here is the same question with a working example
      https://codereview.stackexchange.com/questions/274781/qt-creating-a-dark-overlay-to-apply-on-top-of-other-widgets-with-animation

      1 Reply Last reply
      0

      1/2

      9 Mar 2022, 13:24

      • Login

      • Login or register to search.
      1 out of 2
      • First post
        1/2
        Last post
      0
      • Categories
      • Recent
      • Tags
      • Popular
      • Users
      • Groups
      • Search
      • Get Qt Extensions
      • Unsolved