Qt 拖拽 动态 垃圾箱
来源:互联网 发布:九阴绝学金身升级数据 编辑:程序博客网 时间:2024/05/14 20:10
前些天看了Qt的拖拽,觉得Qt的拖拽还是蛮灵活;但widgets在移动端类似的app应用场景下,确实显得有一些笨拙;但同时它功能强大,灵活性非常高。
我在这里实现的是一个类似于android手机卸载软件时的动态垃圾箱。先看下效果是这样的。
支持自动缩放,自适应啰。
被拖动的目标显然用QListWidget来存放最方便,这也是拖拽的一个典型应用。垃圾箱的动画使用了QPropertyAnimation,其它的就是拖拽的事件监听了;下面请看代码
#include "widget.h"#include <QApplication>#include <QListWidget>#include <QPropertyAnimation>#include <QVBoxLayout>#include <QPushButton>#include <QBitmap>#include <QPainter>#include <QResizeEvent>#include <QDebug>Widget::Widget(QWidget *parent) : QWidget(parent){ QVBoxLayout *lay = new QVBoxLayout(this); listWidget = new QListWidget; listWidget->setViewMode(QListWidget::IconMode); //设置显示方式 listWidget->addItem(new QListWidgetItem(QIcon(":/img/test.png"),QStringLiteral("test"))); //放一个item到ListWidget listWidget->addItem(new QListWidgetItem(QIcon(":/img/trash.png"),QStringLiteral("trash")));//放一个item到ListWidget listWidget->installEventFilter(this); //为ListWidget添加事件监听,用于检测item项是否被拖动 lay->addWidget(listWidget); //主布局 reRect = new QLabel(this); //顶上垃圾箱背景label reRect->setAutoFillBackground(true); QPalette pal = reRect->palette(); pal.setBrush(QPalette::Background,Qt::lightGray); //设置背景色 reRect->setPalette(pal); QPixmap pix(":/img/trash.png"); reRect->resize(width(),pix.height() + 20); //重设label尺寸 reRect->setMinimumHeight(pix.height() + 20); reLabel = new QLabel; //垃圾桶 reLabel->resize(pix.size()); //重调垃圾桶label尺寸 reLabel->setPixmap(pix); reLabel->setMask(pix.mask()); reLabel->setAcceptDrops(true); //使能够接受拖拽的落下 reLabel->installEventFilter(this); //添加事件监听 QHBoxLayout *hlay = new QHBoxLayout(reRect); hlay->addWidget(reLabel,0,Qt::AlignCenter); //在背景label中居中 ani = new QPropertyAnimation(reRect, "geometry"); //新建动画,绑定属性为背景label的geometry ani->setEasingCurve(QEasingCurve::InCurve); //设置动画插值方式 ani->setDuration(150); //动画持续时间 connect(ani,&QPropertyAnimation::finished,[&]{ani->setDirection(QAbstractAnimation::Direction(!ani->direction()));}); //改变方向}void Widget::resizeEvent(QResizeEvent *event){ reRect->resize(event->size().width(),reRect->height()); //当窗口发生变化时,重调背景label尺寸 if(initFlag){ //当第一次初始化时,移动到窗体外面 initFlag = false; reRect->move(reRect->x(),-reRect->height()); } ani->setStartValue(QRect(reRect->x(),-reRect->height(),reRect->width(),reRect->height())); //设置动画起点值 ani->setEndValue(reRect->rect()); //设置动画终点值 return QWidget::resizeEvent(event);}Widget::~Widget(){}bool Widget::eventFilter(QObject *watched, QEvent *event){ if(reLabel = qobject_cast<QLabel*>(watched)){ if(event->type() == QEvent::DragEnter){ QDragEnterEvent *drageEnterE{nullptr}; try{ drageEnterE = dynamic_cast<QDragEnterEvent*>(event); }catch(std::bad_cast &e){ qDebug() << e.what(); } if(drageEnterE){ trashPainted = false; drageEnterE->acceptProposedAction(); //当拖拽事件进入时,启用接收拖拽 } return true; }else if(event->type() == QEvent::Drop){ QDropEvent *dropE{nullptr}; try{ dropE = dynamic_cast<QDropEvent*>(event); }catch(std::bad_cast &e){ qDebug() << e.what(); } if(dropE){ listWidget->takeItem(listWidget->row(listWidget->currentItem())); //当在垃圾箱落下时,从ListWidget中删除当前项,并恢复垃圾箱颜色 QPixmap *pix = const_cast<QPixmap*>(reLabel->pixmap()); *pix = QPixmap(":/img/trash.png"); reLabel->repaint(); } return true; }else if(event->type() == QEvent::DragMove){ QDragMoveEvent *mvEvent{nullptr}; try{ mvEvent = dynamic_cast<QDragMoveEvent*>(event); }catch(std::bad_cast &e){ qDebug() << e.what(); } if(mvEvent && !trashPainted){ //当item项在垃圾箱上漂荡时,改变垃圾箱颜色 QPixmap *pix = const_cast<QPixmap*>(reLabel->pixmap()); QPainter p(pix); p.initFrom(pix); p.fillRect(pix->rect(),QColor(200,0,0,50)); reLabel->repaint(); trashPainted = !trashPainted; } return true; }else if(event->type() == QEvent::DragLeave){ QDragLeaveEvent *leEvent{nullptr}; try{ leEvent = dynamic_cast<QDragLeaveEvent*>(event); }catch(std::bad_cast &e){ qDebug() << e.what(); } if(leEvent){ QPixmap *pix = const_cast<QPixmap*>(reLabel->pixmap()); //当拖拽事件离开时,恢复垃圾箱颜色 *pix = QPixmap(":/img/trash.png"); reLabel->repaint(); } return true; } }else if(listWidget == qobject_cast<QListWidget*>(watched)){ QChildEvent *childEvent{nullptr}; switch (event->type()) { case QEvent::ChildAdded: try{ childEvent = dynamic_cast<QChildEvent*>(event); }catch(std::bad_cast &e){ qDebug() << e.what(); } if(childEvent){ //当item项被视为拖动时,启动动画 ani->start(); } break; case QEvent::ChildRemoved: try{ childEvent = dynamic_cast<QChildEvent*>(event); }catch(std::bad_cast &e){ qDebug() << e.what(); } if(childEvent){ //当item拖动结束时,启动动画 ani->start(); } break; } } return QWidget::eventFilter(watched,event);}
我做得比较简单,如果完美一点,应该在最后那段代码中;当item被拖动时应该判断动画执行方向,如果此时动画还是离开窗体中,就应该先停止动画,然后改变方向,再启动动画;当拖动结束时也是一样的。不过我这里设置的动画持续时间比较短,这个现象问题不大。
需要源码可到处下载
阅读全文
0 0
- Qt 拖拽 动态 垃圾箱
- 垃圾箱
- Braun概念垃圾箱设计
- suse 垃圾箱位置
- MyEclipse垃圾箱设置
- hadoop运维--开启垃圾箱
- L3-005. 垃圾箱分布
- L3-005. 垃圾箱分布
- L3-005. 垃圾箱分布
- Qt动态加载动态库
- rm 删除文件到垃圾箱
- rm 删除文件到垃圾箱
- 仿网易‘垃圾箱’动画效果
- 垃圾箱广告发布的优势
- linux命令清空垃圾箱
- [Qt]动态库--window
- QT 加载动态库
- Qt动态语言切换
- 超初级的用Python收集杂乱字符串中的特定字符,统计出每个特定字符的出现次数并取出最小值
- 171206-类与对象【连续第四十二天】
- opencv之画图(Drawing Functions in OpenCV )
- thinkphp3.2 中用S方法实现 用户定时操作
- 利用Swoole实现PHP+websocket 聊天室
- Qt 拖拽 动态 垃圾箱
- 查看APK的签名的方法
- BZOJ4059: [Cerc2012]Non-boring sequences
- 剑指offer—调整数组顺序使奇数位于偶数前面
- C++进阶—>_beginthreadex和CreateThread的区别和联系
- 人工智能发展中的道德困境
- 集合Hash哈希
- 矩阵中的路径
- 网站发布到服务器后cookie无法登录问题