很重要--轉載聲明
- 本站文章無特別說明,皆爲原創,版權全部,轉載時請用連接的方式,給出原文出處。同時寫上原做者:朝十晚八 or Twowords
- 如要轉載,請原文轉載,如在轉載時修改本文,請事先告知,謝絕在轉載時經過修改本文達到有利於轉載者的目的。
最近作了一個提示框消失的功能,覺着挺有意思,之前一直覺得Qt子窗口不能作淡出效果,其實Qt的淡出功能已經幫咱們封裝好了,咱們僅僅只須要幾行代碼就能夠作出酷炫的窗口關閉效果,寫此篇文章的時候,我特地瀏覽了下以前寫的兩篇文章(QPainterPath 不規則提示框,QPainterPath 不規則提示框(二)),如今回想起來那會兒確實知之甚少,關於頂層窗口不能作圓角,其實幫助文檔裏已經說的很明確,解決辦法有多種,一種是重寫paintEvent函數,另外一種是把widget包裝一層,本篇文章就用的是後一種方式,如圖1所示窗口關閉動畫,實例程序中作了淡出、飛出、縮小等關閉窗口動畫,除此以外還包含了陰影、背景着色、濾鏡等特效。html
圖1 窗口特效函數
如圖1窗口特效所示,實例中總共包含了4個groupbox,這4個groupbox是分別用來展現不一樣特效,下面分別講述4個groupboxpost
在講解代碼以前,先來認識幾個概念測試
一、移出動畫,使用屬性動畫QPropertyAnimation類進行,propertyname的參數是窗口的屬性,詳情參見Q_PROPERTY屬性 。targetObject對象設置爲this內部單獨封裝的widget,這樣作的目的使得該提示框不須要依賴其餘窗口遮擋便可作出飛出效果動畫
1 void GMPOperateTip::MoveOut() 2 { 3 m_pAnimation->setTargetObject(m_pMoveWidget); 4 m_pAnimation->setPropertyName("pos"); 5 6 m_pAnimation->setStartValue(QPoint()); 7 switch (m_eDirection) 8 { 9 case D_LEFT: 10 m_pAnimation->setEndValue(QPoint(-width(), 0)); 11 break; 12 case D_TOP: 13 m_pAnimation->setEndValue(QPoint(0, -height())); 14 break; 15 case D_RIGHT: 16 m_pAnimation->setEndValue(QPoint(width(), 0)); 17 break; 18 case D_BOTTOM: 19 m_pAnimation->setEndValue(QPoint(0, height())); 20 break; 21 default: 22 ; 23 } 24 }
二、淡出this
1 m_pOpacity = new QGraphicsOpacityEffect(this); 2 m_pOpacity->setOpacity(1); 3 4 setGraphicsEffect(m_pOpacity); 5 6 m_pAnimation->setTargetObject(m_pOpacity); 7 m_pAnimation->setPropertyName("opacity"); 8 9 m_pAnimation->setStartValue(1); 10 m_pAnimation->setEndValue(0);
三、最小化url
1 m_pAnimation->setPropertyName("geometry"); 2 3 QRect startRect = rect(); 4 startRect.moveTo(pos()); 5 QRect stopRect = QRect(startRect.center(), QSize(0, 0)); 6 7 m_pAnimation->setStartValue(startRect); 8 m_pAnimation->setEndValue(stopRect);
四、動畫啓動機制spa
使用定時器控制動畫,當指定時間後啓動動畫,而且在動畫完成後關閉窗口.net
1 void InitializeConnect() 2 { 3 m_pAnimation = new QPropertyAnimation(this); 4 m_pAnimation->setTargetObject(this); 5 6 connect(m_pAnimation, &QPropertyAnimation::finished, this, &GMPOperateTip::close); 7 8 connect(&m_StayTimer, &QTimer::timeout, this, [this]{ 9 m_pAnimation->setDuration(m_DurationTime); 10 switch (m_eMode) 11 { 12 case AM_FADEOUT: 13 FadeOut_p(); 14 break; 15 case AM_FLYOUT: 16 MoveOut(); 17 break; 18 case AM_ZOOMIN: 19 ZoomIn(); 20 break; 21 default: 22 ; 23 } 24 25 m_pAnimation->start(); 26 }); 27 }
窗口顯示時啓動定時器,而且將窗口隨機移動到屏幕一個位置3d
1 bool event(QEvent * e) 2 { 3 if (e->type() == QEvent::Show) 4 { 5 //QPoint pos = parentWidget()->rect().center() - this->rect().center(); 6 int wrand = qrand() % (parentWidget()->rect().width() - this->rect().width()); 7 int hrand = qrand() % (parentWidget()->rect().height() - this->rect().width()); 8 move(QPoint(wrand, hrand)); 9 10 m_StayTimer.start(m_iStayDuration); 11 } 12 13 return __super::event(e); 14 }
五、陰影
1 void setShadowEnable(bool enable) 2 { 3 if (!m_pShadow) 4 { 5 m_pShadow = new QGraphicsDropShadowEffect(this); 6 m_pShadow->setColor(QColor(0, 0, 0, 85)); 7 m_pShadow->setBlurRadius(10); 8 m_pShadow->setOffset(4, 4); 9 } 10 11 setGraphicsEffect(enable ? m_pShadow : nullptr); 12 }
六、着色
註釋中的代碼也能夠進行着色,可是窗體的一些特殊樣式不能完成,所以使用stylesheet來完成背景色修改
1 static const QString c_szStyleSheet = "QWidget{background-color:%1;\ 2 border:1px solid %2;border-top:0;border-bottom-left-radius:3px;\ 3 border-bottom-right-radius:3px;background-image: url();}";
1 void GMPOperateTip::setBackgroundColor(const QColor & color) 2 { 3 //if (!m_pColorize) 4 //{ 5 // m_pColorize = new QGraphicsColorizeEffect(this); 6 // m_pColorize->setStrength(1); 7 // 8 // setGraphicsEffect(m_pColorize); 9 //} 10 //m_pColorize->setColor(color); 11 12 QColor border = color; 13 border.setAlpha(255 * 0.1); 14 QString borderRgba = QString("rgba(%1,%2,%3,%4)").arg(border.red()).arg(border.green()).arg(border.blue()).arg(border.alpha()); 15 setStyleSheet(c_szStyleSheet.arg(color.name()).arg(borderRgba)); 16 }
七、快捷調用接口,該接口都是類的靜態方法能夠直接調用
八、測試,因爲測試代碼較多,我只貼出2個
1 void tip::on_pushButton_success_clicked()
2 { 3 GMPOperateTip::Success(this, QStringLiteral("測a試º?,ê?測a試º?"), 1000, 1000); 4 } 5 6 void tip::on_pushButton_warning_clicked() 7 { 8 GMPOperateTip::Waring(this, QStringLiteral("測a試º?,ê?測a試º?"), 1000, 1000); 9 }