QT如何实现控件倒影特效

QT如何实现控件倒影特效

在工作中,我们有时会有以下需求:

想要为某些控件不只是图片加倒影特效,例如:
这样:
这里写图片描述
例如:
这样:
这里写图片描述
于是,在我的潜心研究之下,终于找到了两种实现方法:
(一)使用QT的QGraphicsEffect类
QGraphicsEffect类是一个强大的特效类,但是官方只有四种用法,做倒影是不够的,因此,需要我们自己重新定义一个类来继承它,重写它的draw方法,完成我们的倒影特效。具体代码如下:

getmirror.h

#ifndef GETMIRROR_H
#define GETMIRROR_H

#include <QObject>
#include <QGraphicsEffect>
#include <QPainter>

class GetMirror : public QGraphicsEffect
{
    Q_OBJECT
public:
    GetMirror();
    void draw(QPainter *painter);
};

#endif // GETMIRROR_H

getmirror.cpp

#include "getmirror.h"
#include <QPixmap>

GetMirror::GetMirror()
{

}

void GetMirror::draw(QPainter *painter)
{
    QPixmap pixmap;
    pixmap = sourcePixmap(Qt :: DeviceCoordinates);

    painter->save();
    painter->drawPixmap(0,0,pixmap);
    painter->setOpacity(0.2);
    painter->scale(1,-1);
    painter->translate(0,-pixmap.height());
    painter->drawPixmap(0,0,pixmap);
    painter->restore();
}

通过重写draw方法,完成实现倒影特效,然后在mainwindow里面调用,对于all class都有一个方法叫setGraphicsEffect,通过此方法,就可将特效加到widget上面了。

mainwindow.h

#ifndef MAINWINDOW_H
#define MAINWINDOW_H

#include <QMainWindow>
#include <QPushButton>
#include "getmirror.h"

class MainWindow : public QMainWindow
{
    Q_OBJECT

public:
    MainWindow(QWidget *parent = 0);

    ~MainWindow();

private:
    GetMirror *pgetMirror;
    QPushButton *pBtn;
};

#endif // MAINWINDOW_H

mainwidow.cpp

#include "mainwindow.h"
#include <QLabel>

MainWindow::MainWindow(QWidget *parent)
    : QMainWindow(parent)
{
    setMinimumSize(300,300);
    setMaximumSize(300,300);
    QPalette pal(this->palette());

    //设置背景黑色
    pal.setColor(QPalette::Background, Qt::black);
    this->setAutoFillBackground(true);
    this->setPalette(pal);

    pgetMirror = new GetMirror();

    pBtn = new QPushButton(this);
    pBtn->setText("This is a Button");
    pBtn->setGeometry(75,100,150,50);

    this->setGraphicsEffect(pgetMirror);

    connect(pBtn,SIGNAL(clicked(bool)),this,SLOT(close()));
}

MainWindow::~MainWindow()
{

}

最终实现结果:
这里写图片描述
但是,这种方法有一个缺点,它始终是将你所要实现倒影部分的上半部分变为倒影,因为对于QPainter来说,它的整个绘图区域只有你的目标那么大。

下来给大家介绍第二种方式,可以只为您所需要的控件添加倒影特效。

(二)通过QPainter绘制出它的倒影
这种方式理论上来讲也不是很难,只需要将所需控件截图出来,然后通过QPainter绘制出它的倒影放在相应位置即可。

自己定义一个widget类,所有的操作只在这个widget上进行。
reflect.h

#ifndef REFLECT_H
#define REFLECT_H

#include <QWidget>
#include <QPushButton>
#include <QLabel>
#include <QPixmap>

class Reflect : public QWidget
{
public:
    Reflect();
    void paintEvent(QPaintEvent*);

public:
    QPushButton *pBtn;
    QLabel* pLabel;
    QPixmap* pix;
};

#endif // REFLECT_H

reflect.cpp

#include "reflect.h"
#include <QVBoxLayout>
#include <QPainter>
#include <QDateTime>
#include <QDebug>

Reflect::Reflect()
{
    setMinimumSize(500,500);

    QPalette pal(this->palette());
    pal.setColor(QPalette::Background, Qt::black);
    this->setAutoFillBackground(true);
    this->setPalette(pal);

    pBtn = new QPushButton(this);
    pBtn->setText("This is a Button");
    pBtn->setGeometry(0,50,300,100);

    pix = new QPixmap;
    *pix = QPixmap::grabWidget(pBtn);
}

void Reflect::paintEvent(QPaintEvent *)
{
    QPainter painter(this);
    painter.translate(0,150); //将(0,100)设为坐标原点
    painter.save();
    painter.setOpacity(0.2);
    painter.scale(1,-1);
    painter.translate(0,-100);
    painter.drawPixmap(0,0,*pix);
    painter.restore();
}

通过重写paintEvent方法来实现所需特效

mainwindow.h

#ifndef MAINWINDOW_H
#define MAINWINDOW_H

#include <QMainWindow>
#include <QPushButton>
#include "reflect.h"

class MainWindow : public QMainWindow
{
    Q_OBJECT

public:
    MainWindow(QWidget *parent = 0);

    ~MainWindow();

private:
    QPushButton *pBtn;
    Reflect *pReflect;
};

#endif // MAINWINDOW_H

mainwindow.cpp

#include "mainwindow.h"
#include <QLabel>

MainWindow::MainWindow(QWidget *parent)
    : QMainWindow(parent)
{
    pReflect = new Reflect();
    pReflect->show();
}

MainWindow::~MainWindow()
{

}

最终实现结果:
这里写图片描述

至此,两种方法已经介绍完毕

最新版传送门:QT实现控件倒影特效 2.0:http://blog.csdn.net/fan_xingwang/article/details/79034369

猜你喜欢

转载自blog.csdn.net/fan_xingwang/article/details/78982571