Qt

2013-10-15 8 views
6

में QWidget पर धुंध प्रभाव Qt में विजेट को धुंधला करने का कोई तरीका है? उदाहरण के लिए, मान लीजिए कि मैं 'लोड हो रहा हूं ...' संवाद बनाना चाहता हूं और पृष्ठभूमि को धुंधला करना चाहता हूं (सक्रिय विंडो नहीं)।Qt

उत्तर

8

यह उत्तर मेरे ओवरले से संबंधित उत्तरों की एक श्रृंखला में है: first, second, third

यदि आप सभी प्लेटफॉर्म पर काम करना चाहते हैं तो इसे कुछ देखभाल की आवश्यकता है। आप सीधे शीर्ष-स्तरीय विंडो पर प्रभाव लागू नहीं कर सकते हैं। पदानुक्रम कुछ ऐसा नज़र करने की जरूरत है:

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

आप Target विजेट के लिए प्रभाव लागू (जैसे कि, एक QMainWindow)। ContainerWidget एक सहायक वर्ग है जो बच्चों को विजेट के पूर्ण आकार पर कब्जा रखता है। यह एक स्पष्ट शून्य-मार्जिन लेआउट की आवश्यकता को रोकता है।

नीचे दिए गए काम, मैक पर भी। यह नहीं होगा, क्या आपने ContainerWidget का आगाह किया था। यह दुर्भाग्य से केवल क्यूटी 5 पर काम करता है। Qt 4 पर, अपने "क्रॉस प्लेटफॉर्म" समर्थन शामिल नहीं मैक :(यह या तो क्यूटी 4 (4.8.5) या क्यूटी 5.

screenshot

// https://github.com/KubaO/stackoverflown/tree/master/questions/overlay-blur-19383427 
#include <QtGui> 
#if QT_VERSION >= QT_VERSION_CHECK(5,0,0) 
#include <QtWidgets> 
#endif 

class OverlayWidget : public QWidget 
{ 
    void newParent() { 
     if (!parent()) return; 
     parent()->installEventFilter(this); 
     raise(); 
    } 
public: 
    explicit OverlayWidget(QWidget * parent = {}) : QWidget{parent} { 
     setAttribute(Qt::WA_NoSystemBackground); 
     setAttribute(Qt::WA_TransparentForMouseEvents); 
     newParent(); 
    } 
protected: 
    //! Catches resize and child events from the parent widget 
    bool eventFilter(QObject * obj, QEvent * ev) override { 
     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); 
    } 
    //! Tracks parent widget changes 
    bool event(QEvent* ev) 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 = {}) : QWidget{parent} {} 
    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) override { 
     if (ev->type() == QEvent::ChildAdded) { 
     setSize(static_cast<QChildEvent*>(ev)->child()); 
     } 
     return QWidget::event(ev); 
    } 
    //! Keeps the children appropriately sized 
    void resizeEvent(QResizeEvent *) override { 
     for(auto obj : children()) setSize(obj); 
    } 
}; 

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

#if QT_VERSION < QT_VERSION_CHECK(5,0,0) 
template <typename F> void singleShot(int period, F && fun) { 
    struct Helper : public QObject { 
     F fun; 
     QBasicTimer timer; 
     void timerEvent(QTimerEvent * event) override { 
     if (event->timerId() != timer.timerId()) return; 
     fun(); 
     deleteLater(); 
     } 
     Helper(int period, F && fun) : fun(std::forward<F>(fun)) { 
     timer.start(period, this); 
     } 
    }; 
    new Helper(period, std::forward<F>(fun)); 
} 
#else 
template <typename... Args> 
auto singleShot(Args&&... args) -> decltype(QTimer::singleShot(std::forward<Args>(args)...)) { 
    return QTimer::singleShot(std::forward<Args>(args)...); 
} 
#endif 

int main(int argc, char *argv[]) 
{ 
    QApplication a{argc, argv}; 
    ContainerWidget base; 
    QLabel label("Dewey, Cheatem and Howe, LLC.", &base); 
    label.setFont({"times,times new roman", 32}); 
    label.setAlignment(Qt::AlignCenter); 
    label.setGraphicsEffect(new QGraphicsBlurEffect); 
    LoadingOverlay overlay(&base); 
    base.show(); 
    singleShot(2000, [&]{ 
     overlay.hide(); 
     label.setGraphicsEffect({}); 
    }); 
    return a.exec(); 
} 
विंडोज पर ठीक काम करता है
0

यदि आप किसी छवि पर धुंध प्रभाव लागू करना चाहते हैं तो आप this आलेख का संदर्भ ले सकते हैं। अपनी धुंधली छवि बनाने के बाद आप इसे QWidget::paintEvent() फ़ंक्शन में खींच सकते हैं।

संबंधित मुद्दे