標籤:
原文地址: http://blog.sina.com.cn/s/blog_a6fb6cc90101eoc7.html
陰影邊框很常見,諸如360以及其他很多軟體都有類似效果,瞭解CSS3的同學們應該都知道box-shadow,它就是來設定陰影製作效果的,那麼Qt呢?看過一些資料,說是QSS是基於CSS2的,既然如此,box-shadow是基於CSS3的!那麼Qt定然就用不了!
搜了一些資料,每張圖片都做成陰影製作效果的固然不可能,直接捨棄(即使可以,也不採納)。如果即時的去畫圖,效率太低,最後選擇了拼圖的方式! 效果如下: 左上方、左下角、右上方、右下角、上、下、左、右,這幾個方向都繪製對應的圖即可! #include "shadow_widget.h" ShadowWidget::ShadowWidget(QWidget *parent) : QDialog(parent){ setWindowFlags(Qt::FramelessWindowHint | Qt::Dialog); setAttribute(Qt::WA_TranslucentBackground);} ShadowWidget::~ShadowWidget(){ } void ShadowWidget::paintEvent(QPaintEvent *event){ QPainter painter(this); this->drawShadow(painter); painter.setPen(Qt::NoPen); painter.setBrush(Qt::white); painter.drawRect(QRect(SHADOW_WIDTH, SHADOW_WIDTH, this->width()-2*SHADOW_WIDTH, this->height()-2*SHADOW_WIDTH));} void ShadowWidget::drawShadow(QPainter &painter){ //繪製左上方、左下角、右上方、右下角、上、下、左、右邊框 QList pixmaps; pixmaps.append(QPixmap(":/shadow/shadow_left")); pixmaps.append(QPixmap(":/shadow/shadow_right")); pixmaps.append(QPixmap(":/shadow/shadow_top")); pixmaps.append(QPixmap(":/shadow/shadow_bottom")); pixmaps.append(QPixmap(":/shadow/shadow_left_top")); pixmaps.append(QPixmap(":/shadow/shadow_right_top")); pixmaps.append(QPixmap(":/shadow/shadow_left_bottom")); pixmaps.append(QPixmap(":/shadow/shadow_right_bottom")); painter.drawPixmap(0, 0, SHADOW_WIDTH, SHADOW_WIDTH, pixmaps[4]); painter.drawPixmap(this->width()-SHADOW_WIDTH, 0, SHADOW_WIDTH, SHADOW_WIDTH, pixmaps[5]); painter.drawPixmap(0,this->height()-SHADOW_WIDTH, SHADOW_WIDTH, SHADOW_WIDTH, pixmaps[6]); painter.drawPixmap(this->width()-SHADOW_WIDTH, this->height()-SHADOW_WIDTH, SHADOW_WIDTH, SHADOW_WIDTH, pixmaps[7]); painter.drawPixmap(0, SHADOW_WIDTH, SHADOW_WIDTH, this->height()-2*SHADOW_WIDTH, pixmaps[0].scaled(SHADOW_WIDTH, this->height()-2*SHADOW_WIDTH)); painter.drawPixmap(this->width()-SHADOW_WIDTH, SHADOW_WIDTH, SHADOW_WIDTH, this->height()-2*SHADOW_WIDTH, pixmaps[1].scaled(SHADOW_WIDTH, this->height()- 2*SHADOW_WIDTH)); painter.drawPixmap(SHADOW_WIDTH, 0, this->width()-2*SHADOW_WIDTH, SHADOW_WIDTH, pixmaps[2].scaled(this->width()-2*SHADOW_WIDTH, SHADOW_WIDTH)); painter.drawPixmap(SHADOW_WIDTH, this->height()-SHADOW_WIDTH, this->width()-2*SHADOW_WIDTH, SHADOW_WIDTH, pixmaps[3].scaled(this->width()-2*SHADOW_WIDTH, SHADOW_WIDTH));} 寫一個公用的類,如果視窗要實現陰影製作效果直接繼承就行了!SHADOW_WIDTH為陰影邊框的像素,可以根據自己的需求自由調節! 也可使用QGraphicsDropShadowEffect來實現。。。 更多參考:Qt之再談陰影邊框. 前面就視窗陰影已經寫過一篇部落格,使用九宮格的思路實現的,在我看來,凡是用程式能實現的盡量不要使用圖片代替(在保證效率的前提下),今天再次分享關於我的一些小見解! 先看效果: 視窗陰影任意調節,包括陰影像素、是否圓角等。 直接上代碼: void DropShadowWidget::paintEvent(QPaintEvent *event){ QPainterPath path; path.setFillRule(Qt::WindingFill); path.addRect(10, 10, this->width()-20, this->height()-20); QPainter painter(this); painter.setRenderHint(QPainter::Antialiasing, true); painter.fillPath(path, QBrush(Qt::white)); QColor color(0, 0, 0, 50); for(int i=0; i<10; i++) { QPainterPath path; path.setFillRule(Qt::WindingFill); path.addRect(10-i, 10-i, this->width()-(10-i)*2, this->height()-(10-i)*2); color.setAlpha(150 - qSqrt(i)*50); painter.setPen(color); painter.drawPath(path); }} 記得加上這行代碼:setAttribute(Qt::WA_TranslucentBackground)。保證不被繪製上的部分透明,關於這行代碼在一些Qt版本中會有副作用,比如:最小化後表單子組件失去焦點等問題。具體可以看Qt的這個Bug(Widget with Qt::FramelessWindowHint and Qt::WA_TranslucentBackground stops painting after minimize/restore)。 也許有人會遇到,因為我之前一直使用的是VS整合Qt5外掛程式(非OpenGL版本),一直存在這個問題,尋找各方面資料無果(真的很久,搞不誇張的說大半年應該是有的)。最後改換OpenGL版本的居然好了。。。問題的解決方式太過於詭異,真讓人哭笑不得。在此記過,希望對後來人有協助。 為子組件添加陰影比較簡單,使用如下方式:QGraphicsDropShadowEffect *shadow_effect = new QGraphicsDropShadowEffect(this);shadow_effect->setOffset(-5, 5);shadow_effect->setColor(Qt::gray);shadow_effect->setBlurRadius(8);network_group_box->setGraphicsEffect(shadow_effect); 效果如下:
Qt之陰影邊框(轉)