前些天看了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到ListWidgetlistWidget->addItem(new QListWidgetItem(QIcon(":/img/trash.png"),QStringLiteral("trash")));//放一个item到ListWidgetlistWidget->installEventFilter(this); //为ListWidget添加事件监听,用于检测item项是否被拖动lay->addWidget(listWidget); //主布局reRect = new QLabel(this);            //顶上垃圾箱背景labelreRect->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的geometryani->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被拖动时应该判断动画执行方向,如果此时动画还是离开窗体中,就应该先停止动画,然后改变方向,再启动动画;当拖动结束时也是一样的。不过我这里设置的动画持续时间比较短,这个现象问题不大。

需要源码可到处下载

Qt 拖拽 动态 垃圾箱相关推荐

  1. qt 拖拽 修改大小(二)

    最近项目需要实现windows下橡皮筋的效果,所以对此做了一些了解,特此记录. 首先windows系统是支持橡皮筋效果的,需要使用win32方 法:SystemParametersInfo(SPI_S ...

  2. qt 拖拽 修改大小

    写次篇文章之前,qt窗口的放大缩小和拖拽我都是通过setGeometry方法实现的,但是作为windows程序,windows支持橡 皮筋式(拖拽时有一个虚框)拖拽和拉伸.通过setGeometry方 ...

  3. 拖拽动态生成网页-VvvebJs

    VvvebJs是一个开源的网页拖拽自动生成的JavaScript库,你可以以简单拖拽的方式生成自己需要的网页样式,内置jquery和Bootstrap,你可以拖拽相关的组件进行网页的构建,非常的方便, ...

  4. python qt 拖拽组件使用方法_Python QT组件库qtwidgets的使用

    虽然Qt提供了不少现成的组件,但是在Python中使用PyQt5或PySide2进行图形界面程序开发的过程,还是免不了要根据自己的需求组合一些小部件以形成新的自定义组件. 最近州的先生在写一个桌面图形 ...

  5. Qt中自定义控件拖拽,QT实现拖拽功能--小白友好版

    目录 创作背景 开发环境 运行效果 实现原理 1.参考文档 2.主要原理 实现过程 1.首先是重写QLabel 2.第二步是使用自己写的Label类 总结 创作背景         写这篇文章主要有一 ...

  6. Qt之QToolButton 实现动态拖拽Drag、Drop功能

    简述 最近在做一个项目需要实现工具的动态添加功能,想来想去也只有动态拖拽最为直观,于是摸索了几天才摸索明白,最后选择了QToolButton作为载体重写了一下.当然也可以选择QPushButton作为 ...

  7. html组态图动态拖拽,基于HTML5的Drag and Drop生成图片Base64信息

    HTML5的Drag and Drop是很不错的功能,网上使用例子较多如 http://html5demos.com/drag ,但这些例子大部分没实际用途,本文将搞个有点使用价值的例子,通过Drag ...

  8. Qt之QAbstractItemView视图项拖拽(二)

    一.需求说明 上一篇文章Qt之QAbstractItemView视图项拖拽(一)讲述了实现QAbstractItemView视图项拖拽的一种方式,是基于QDrag实现的,这个类是qt自己封装好了的,所 ...

  9. Qt工作笔记-ListWidget拖动(拖拽)到QGraphicsScene【补坑】【Qt视图框架补坑】

    关于以前的这篇博文,进行补坑 https://blog.csdn.net/qq78442761/article/details/80957186 坑的位置在这,采用上面这篇博文的配法,无法得到图元在场 ...

最新文章

  1. 怎样生成分布式情况下的唯一标示?必须包含网卡字段,以便不同机器生成的唯一标示肯定不一样...
  2. 64位Linux下的栈溢出
  3. 概率检索模型:BIM+BM25+BM25F
  4. Sql server时间转时间long
  5. P5956-[POI2017]Podzielno【数学】
  6. JavaFX技巧10:自定义复合控件
  7. SUSE,为企业云原生打造多模平台
  8. springboot(十二)-分布式锁(redis)
  9. Java开发岗位面试题
  10. mybatisplus page排序_MyBatisPlus分页的同时指定排序规则说明
  11. mysql int 拼接_MySQL 修改int类型为bigint SQL语句拼接
  12. html图片自动剪裁,HTML canvas图像裁剪
  13. 苹果Mac桌面Dock中App icon 名称显示乱码怎么办?一个简单指令帮你解决
  14. mvc:annotation-driven/与mvc:default-servlet-handler/之间的一个问题(转)
  15. 性能测试--jmeter如何发送post请求【4】
  16. c语言通讯录整体设计论文,通讯录管理系统的设计与实现
  17. python计算ROC曲线和面积AUC
  18. 病毒入侵:全靠分布式 Gossip 协议
  19. 1104-捷径(DP)
  20. 前端开发者应该知道的 CSS 小技巧

热门文章

  1. Vue 计算时间差,几分钟之前、几小时前、几天之前、几个月前
  2. 思科服务器系统时间,cisco 设置时间
  3. python中如何解决类互相调用问题_python中同一个类,带参的方法直接如何相互调用...
  4. 题目目录:java练习题
  5. 扇贝python离线_Python项目:扇贝网小组查卡助手
  6. C语言 字符串分类统计 输入一行字符,分别统计出其中英文字母、数字、空格和其他字符的个数
  7. 单片机内部RAM(片上RAM) 外部RAM(片外RAM)
  8. 精确拐点交易体系之追涨停策略
  9. \\wsl.localhost 无法访问
  10. 【莹伙丛】手把手教你:Gradle 安装及配置