模糊效果QWidget在Qt [英] Blur effect over a QWidget in Qt

查看:277
本文介绍了模糊效果QWidget在Qt的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

有什么办法在Qt模糊一个小部件吗?例如,假设我要创建一个正在加载...对话框并模糊背景(非活动窗口)。

Is there any way to blur a widget in Qt? For instance, supose I want to create a 'Loading...' dialog and blur the background (not active window).

推荐答案

此答案位于一系列与我重叠式广告相关的答案中:第一第二第三

This answer is in a series of my overlay-related answers: first, second, third.

如果你希望它在所有平台上工作,它需要一些注意。您不能将效果直接应用到顶级窗口。层次结构需要如下:

It requires some care if you wish for it to work on all platforms. You can't apply effects directly to top-level windows. The hierarchy needs to look as follows:

ContainerWidget
     |
     +----------+
     |          |
**Target**   Overlay

将效果应用于目标小部件(例如, QMainWindow )。 ContainerWidget 是一个帮助器类,用于保持子元素占用该窗口小部件的完整大小。这样就不需要显式的零边距布局。

You apply the effect to the Target widget (say, a QMainWindow). The ContainerWidget is a helper class that keeps the children occupying the full size of the widget. This obviates the need for an explicit zero-margin layout.

下面的工作,即使在Mac上。它不会,你已经放弃 ContainerWidget 。这只工作在可移植的Qt 5,不幸的是。在Qt 4,你的跨平台支持排除了Mac :(它在Windows上使用Qt 4(4.8.5)或Qt 5工作正常。

The below works, even on a Mac. It wouldn't, had you foregone the ContainerWidget. This works portably on Qt 5 only, unfortunately. On Qt 4, your "cross platform" support excludes Mac :( It works OK on Windows using either Qt 4 (4.8.5) or Qt 5.

#include <QApplication>
#include <QLabel>
#include <QResizeEvent>
#include <QPainter>
#include <QGraphicsBlurEffect>

#ifndef Q_DECL_OVERRIDE
#define Q_DECL_OVERRIDE override
#endif

class OverlayWidget : public QWidget
{
    void newParent() {
        if (!parent()) return;
        parent()->installEventFilter(this);
        raise();
    }
public:
    explicit OverlayWidget(QWidget * parent = 0) : QWidget(parent) {
        setAttribute(Qt::WA_NoSystemBackground);
        newParent();
    }
protected:
    //! Catches resize and child events from the parent widget
    bool eventFilter(QObject * obj, QEvent * ev) Q_DECL_OVERRIDE {
        if (obj == parent()) {
            if (ev->type() == QEvent::Resize) {
                QResizeEvent * rev = static_cast<QResizeEvent*>(ev);
                this->resize(rev->size());
            }
            else if (ev->type() == QEvent::ChildAdded) {
                raise();
            }
        }
        return QWidget::eventFilter(obj, ev);
    }
    //! Tracks parent widget changes
    bool event(QEvent* ev) Q_DECL_OVERRIDE {
        if (ev->type() == QEvent::ParentAboutToChange) {
            if (parent()) parent()->removeEventFilter(this);
        }
        else if (ev->type() == QEvent::ParentChange) {
            newParent();
        }
        return QWidget::event(ev);
    }
};

class ContainerWidget : public QWidget
{
public:
    explicit ContainerWidget(QWidget * parent = 0) : QWidget(parent) {}
    inline void setSize(QObject * obj) {
        if (obj->isWidgetType()) static_cast<QWidget*>(obj)->setGeometry(rect());
    }
protected:
    //! Resizes children to fill the extent of this widget
    bool event(QEvent * ev) Q_DECL_OVERRIDE {
        if (ev->type() == QEvent::ChildAdded) {
            setSize(static_cast<QChildEvent*>(ev)->child());
        }
        return QWidget::event(ev);
    }
    //! Keeps the children appropriately sized
    void resizeEvent(QResizeEvent *) Q_DECL_OVERRIDE {
        foreach(QObject * obj, children()) setSize(obj);
    }
};

class LoadingOverlay : public OverlayWidget
{
public:
    LoadingOverlay(QWidget * parent = 0) : OverlayWidget(parent) {
        setAttribute(Qt::WA_TranslucentBackground);
    }
protected:
    void paintEvent(QPaintEvent *) Q_DECL_OVERRIDE {
        QPainter p(this);
        p.fillRect(rect(), QColor(100, 100, 100, 128));
        p.setPen(QColor(200, 200, 255, 255));
        p.setFont(QFont("arial,helvetica", 48));
        p.drawText(rect(), "Loading...", Qt::AlignHCenter | Qt::AlignTop);
    }
};

int main(int argc, char *argv[])
{
    QApplication a(argc, argv);
    ContainerWidget base;
    QLabel l("Dewey, Cheatem and Howe, LLC.", &base);
    l.setFont(QFont("times,times new roman", 32));
    l.setAlignment(Qt::AlignCenter);
    l.setGraphicsEffect(new QGraphicsBlurEffect);
    LoadingOverlay overlay(&base);
    base.show();
    return a.exec();
}

这篇关于模糊效果QWidget在Qt的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆