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

  • 1
    点赞
  • 12
    收藏
    觉得还不错? 一键收藏
  • 2
    评论
### 回答1: Qt 是一个强大的跨平台 GUI 开发工具包,它提供了很多有用的件和功能,比如件拖拽。下面是一些实现件拖拽的步骤: 1. 在 Qt Creator 中创建一个窗口工程。 2. 在窗口中添加要拖拽的件,如按钮、标签等。 3. 实现件的拖拽功能,可以使用 Qt 的鼠标事件和事件过滤器。 4. 在件上实现鼠标事件,包括鼠标按下、移动和释放等。 5. 实现事件过滤器,以便对件的鼠标事件进行处理。 6. 在件的 mousePressEvent 函数中记录鼠标的坐标,以便在 mouseMoveEvent 函数中使用。 7. 在 mouseMoveEvent 函数中计算件的新坐标,并使用 move 函数将件移动到新的位置。 8. 最后,在 mouseReleaseEvent 函数中实现鼠标释放后的动作,如保存件的位置等。 这些步骤可以帮助你快速实现件拖拽功能,但请注意,实际实现可能因你的项目要求而有所不同。 ### 回答2: 使用Qt实现件的拖拽可以通过以下步骤进行: 1. 首先,需要在Qt的窗口上放置一个可拖拽的件,可以是QPushButton、QLabel等。可以通过在窗口上拖放件或者在代码中创建件。 2. 在拖放源件上,设置Qt的拖放事件,使其能够被拖放到目标件上。可以使用setDragEnabled(true)方法来启用件的拖拽功能。 3. 在目标件上,设置Qt的拖放事件,使其能够接收拖放源件。可以使用setAcceptDrops(true)方法来启用件接收拖放功能。 4. 在拖放源件上,实现mousePressEvent()方法,当鼠标按下时,记录拖放源件的初始位置和鼠标相对于件的位置偏移量。 5. 实现mouseMoveEvent()方法,在该方法中,根据鼠标在窗口中的移动距离,更新拖放源件的位置。 6. 实现dragEnterEvent()方法和dropEvent()方法,在这两个方法中,可以处理拖放源件进入目标件区域和释放拖放源件的行为。 7. 可以根据需要,添加其他相关事件,如mouseReleaseEvent()方法,当鼠标释放时对件进行相应操作。 通过以上步骤,就可以实现使用Qt实现件的拖拽功能。 ### 回答3: 使用Qt实现件拖拽可以通过Qt提供的QDrag和QDropEvent类来实现。 首先,在窗口中需要拖拽的件上设置鼠标按下事件,当鼠标按下时,创建一个QDrag对象,设置拖拽的数据为需要拖拽的件。然后,调用QDrag对象的exec方法启动拖拽操作。示例代码如下: ``` void Widget::mousePressEvent(QMouseEvent *event) { if (event->button() == Qt::LeftButton) { QDrag *drag = new QDrag(this); QMimeData *mimeData = new QMimeData; // 设置拖拽的数据为件的描述信息 mimeData->setText("My Widget"); drag->setMimeData(mimeData); // 开始拖拽操作 drag->exec(); } } ``` 接下来,在需要放置拖拽件的目标窗口中,重写dragEnterEvent和dropEvent事件处理函数。在dragEnterEvent函数中判断拖拽进入的数据类型,如果是需要的件,则设置接受拖拽操作。在dropEvent函数中获取拖拽的数据,并根据数据进行处理。示例代码如下: ``` void TargetWidget::dragEnterEvent(QDragEnterEvent *event) { if (event->mimeData()->hasText() && event->mimeData()->text() == "My Widget") { // 接受拖拽操作 event->acceptProposedAction(); } } void TargetWidget::dropEvent(QDropEvent *event) { // 获取拖拽的数据 QString widgetText = event->mimeData()->text(); // 创建新的件,并根据数据进行处理 QLabel *label = new QLabel(widgetText); // ... // 在目标窗口中放置件 layout()->addWidget(label); } ``` 通过重写鼠标事件和拖拽事件处理函数,可以实现Qt件的拖拽功能。在拖拽开始时设置数据,拖拽结束时获取数据并进行处理。这样就可以在不同的窗口间实现件的拖拽。
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值