簡體   English   中英

Qt QWidget隱藏動畫

[英]Qt QWidget hide animation

我有一個QWidget的子類,它是一個彈出窗口小部件。 我想在它顯示和消失時添加一些動畫。 所以我重新實現了showEvent(QShowEvent * event)hideEvent並在函數中添加了一些QPropertyAnimation showEvent對我來說很好,但hideEvent沒有。 因為

隱藏事件在隱藏后立即發送到窗口小部件。

有什么想法怎么做?

更新:

我不認為這是正確的理由。 當我使用Nejat的解決方案時。 節目部分有效。 但是當我在小部件外面點擊時。 它立即消失。

你應該覆蓋QWidget::closeEvent()所以當試圖立即關閉時它將被忽略並且我們開始動畫並在完成后( QPropertyAnimation::finished() )我們正常關閉小部件。

這是一個演示來演示:

class AnimatedWidget : public QWidget {
    Q_OBJECT
        Q_PROPERTY(qreal alpha READ alpha WRITE setAlpha)

public:
    AnimatedWidget(QWidget* parent = nullptr) :QWidget{ parent }, opacityAnimation{ new QPropertyAnimation{this, "alpha",this} } {
        setWindowFlags(windowFlags() | Qt::WindowFlags(Qt::FramelessWindowHint) | Qt::Tool);
        auto pal = palette();
        pal.setColor(QPalette::Background, Qt::cyan);
        setAutoFillBackground(true);
        setPalette(pal);
        setFixedSize(200, 200);
    }

    qreal alpha() const {
        return windowOpacity();
    }

    void setAlpha(qreal level) {
        setWindowOpacity(level);
        update();
    }

protected:
    void closeEvent(QCloseEvent* e) override {
        if (opacityAnimation->currentValue().toReal() == 1.0) { // Ignore event + start animation
            e->ignore();
            startHide();
            QObject::connect(opacityAnimation, SIGNAL(finished()), this, SLOT(onAnimationCallBack()), Qt::UniqueConnection);
        } else {
            e->accept();
            if (!isHidden())
                hide();
            QWidget::close(); // necessary actions
        }
    }

    public Q_SLOTS:
    void show() {
        startShow();
        QWidget::show(); // necessary actions
    }

    private Q_SLOTS:
    void onAnimationCallBack() {
        if (opacityAnimation->currentValue().toReal() == 0.0) { // we're finished so let's really close the widget
            QCloseEvent ev;
            QApplication::sendEvent(this, &ev);
            qApp->sendEvent(this, &ev);
        }
    }

    void startHide() {
        opacityAnimation->setStartValue(1.0);
        opacityAnimation->setEndValue(0.0);
        opacityAnimation->setDuration(1500);
        opacityAnimation->start();
    }

    void startShow() {
        opacityAnimation->setStartValue(0.0);
        opacityAnimation->setEndValue(1.0);
        opacityAnimation->setDuration(1500);
        opacityAnimation->start();
    }

private:
    QPropertyAnimation* opacityAnimation = nullptr;
};

class Base : public QWidget {
public:
    Base(QWidget* parent = nullptr) :QWidget{ parent }, widget{ new AnimatedWidget{} } {

    }

private:
    AnimatedWidget* widget;

protected:
    void mouseReleaseEvent(QMouseEvent* e) override {
        if (widget->isHidden())
            widget->show();
        else
            widget->close();
        QWidget::mouseReleaseEvent(e);
    }
};

int main(int argc, char *argv[]) {
    QApplication app(argc, argv);
    Base base;
    base.show();
    return app.exec();
}

在此輸入圖像描述

您可以覆蓋窗口小部件中的eventFilter並檢查QEvent::ShowQEvent::Close事件。

bool MyWidget::eventFilter(QObject * obj, QEvent * event)
{
    if(obj == this && event->type() == QEvent::Show)
    {
        //about to show
    }
    else if(obj == this && event->type() == QEvent::Close)
    {
        //about to close
    }


    return false;
}

您還應該通過以下方式在構造函數中安裝事件過濾器:

this->installEventFilter(this);

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM