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