Qt DragDrop拖动与放置

本文章从属于  Qt实验室-CSDN博客系列

拖放操作包括两个动作:拖动(drag)和放下(drop或称为放置)。

拖动允许

对于要拖出的窗口或控件,要setDragEnabled(true)

对于要拖入的窗口或控件,要setAcceptDrops(true)

下面以一个具体的用例进行说明

拖动列表控件中的项目

该用例实现从左边的列表窗口拖出,到右边的Widget窗口拖入

主界面设置

MainWindow::MainWindow(QWidget *parent)
    : QMainWindow(parent)
{
    this->resize(1200,800);
    //从ProjectListWidget拖动到MyWidget上
    QSplitter* center=new QSplitter;
    center->addWidget(new ProjectListWidget);
    center->addWidget(new MyWidget);

    center->setOrientation(Qt::Horizontal);
    this->setCentralWidget(center);
}

 左侧列表窗口设置

class ProjectListWidget : public QListWidget
{
    Q_OBJECT
public:
    ProjectListWidget();

    // QAbstractItemView interface
protected:
    void startDrag(Qt::DropActions supportedActions);
};

 左侧窗口允许拖动其item,并且将item中的文字存入QMimeData,用以传输到右侧窗体中


ProjectListWidget::ProjectListWidget()
{
    this->addItem("item1");
    this->addItem("item2");
    //(1)开启允许拖动,如果不开启是不会有拖动item移动的效果的
    this->setDragEnabled(true);
}

//(2)开始拖动,设置了一种标记为x1的拖动数据
void ProjectListWidget::startDrag(Qt::DropActions supportedActions)
{
    QString text=this->currentItem()->text();
    QMimeData* mimeData=new QMimeData;
    mimeData->setData("x1",text.toLocal8Bit());
    QDrag* drag=new QDrag(this);
    drag->setMimeData(mimeData);
    drag->exec();
}

 右侧窗体的实现会多些,首先必须允许拖拽进入事件dragEnterEvent,然后必须允许拖拽移动事件dragMoveEvent。最后实现dropEvent来接收数据。


MyWidget::MyWidget(QWidget *parent)
    : QWidget{parent}
{
    //(1)开启允许放置,如果不开启,拖动进入界面时将显示禁止符号
    this->setAcceptDrops(true);
}

//(2)实现了以下两个方法后,该界面就能允许拖拽进入了
//对一种被标记为x1的拖动数据允许拖拽进入
void MyWidget::dragEnterEvent(QDragEnterEvent *event)
{
    if (event->mimeData()->hasFormat("x1"))
        event->accept();
    else
        event->ignore();
}

void MyWidget::dragMoveEvent(QDragMoveEvent *event)
{
    if (event->mimeData()->hasFormat("x1"))
        event->accept();
    else
        event->ignore();
}

//(3)实现dropEvent来接收拖动携带的数据
void MyWidget::dropEvent(QDropEvent *event)
{
    if (event->mimeData()->hasFormat("x1"))
    {
        QString text(event->mimeData()->data("x1"));
        QPoint pos=event->pos();
        //在这里将拖动过来的数据放入list,然后通过paintEvent()进行绘制
        m_textList.append({text,pos});
        event->accept();
        this->update();
    }
    else
        event->ignore();
}

void MyWidget::paintEvent(QPaintEvent *event)
{
    QPainter painter(this);

    for(int i=0;i<m_textList.size();i++)
    {
        QPoint pos=m_textList.at(i).second;
        QString text=m_textList.at(i).first;
        painter.drawText(pos,text);
    }
}

最终的效果如下

 

  事件发出顺序和传递规则

上图参考自 Qt拖放(1):拖放基本原理(QDrag类)-CSDN博客

 

关于 QDrag.exec()

void ProjectListWidget::startDrag(Qt::DropActions supportedActions)
{
    //调用该方法的时机,点击item并移动鼠标,即进入该方法
    //然后执行到drag->exec()阻塞
    //exec()函数是一个阻塞函数(但不会阻塞主事件循环)
    //也就是说,在松开鼠标之前,不会打印"after drag"
    //但是窗口依然可以得到其他的事件响应,例如mainwindow依然可以响应QTimer触发的update()
    QString text=this->currentItem()->text();
    QMimeData* mimeData=new QMimeData;
    mimeData->setData("x1",text.toLocal8Bit());
    QDrag* drag=new QDrag(this);
    drag->setMimeData(mimeData);
    qDebug()<<"before drag";
    drag->exec();
    qDebug()<<"after drag";
}

MainWindow中构造时添加如下代码, 

    QTimer* timer=new QTimer(this);
    timer->setInterval(1000);
    connect(timer,&QTimer::timeout,[=]{
        qDebug()<<"update...";
        this->update();
    });
    timer->start();

 测试在拖拽中不释放鼠标时,主窗口能否响应其他的事件(是可以的)

bool MainWindow::event(QEvent *event)
{
    qDebug()<<"event::"<<event;
    return QMainWindow::event(event);
}

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:/a/144255.html

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

Accelerate 0.24.0文档 二:DeepSpeed集成

文章目录 一、 DeepSpeed简介二、DeepSpeed集成&#xff08;Accelerate 0.24.0&#xff09;2.1 DeepSpeed安装2.2 Accelerate DeepSpeed Plugin2.2.1 ZeRO Stage-22.2.2 ZeRO Stage-3 with CPU Offload2.2.3 accelerate launch参数 2.3 DeepSpeed Config File2.3.1 ZeRO Stage-…

什么是 IT 资产管理(ITAM),以及它如何简化业务

IT 资产管理对任何企业来说都是一项艰巨的任务&#xff0c;但使用适当的工具可以简化这项任务&#xff0c;例如&#xff0c;IT 资产管理软件可以为简化软件和硬件的管理提供巨大的优势。 什么是 IT 资产管理 IT 资产管理&#xff08;ITAM&#xff09;是一组业务实践&#xff…

【3dMax室内照明】如何在V-ray中设置照明分析?

如何在V-ray中设置照明分析&#xff1f; 在3dMax的V-Ray Next中添加了新的“照明分析”工具&#xff0c;以帮助您测量和分析场景中的灯光级别。您将能够创建假彩色热图和数据覆盖&#xff0c;以显示亮度&#xff08;以坎德拉为单位&#xff09;或照度&#xff08;以勒克斯为单位…

每天一点python——day67

#每天一点Python——67 #字符串判断方法&#xff1a;如图&#xff1a; #①判断指定字符串是否为合法标识符 shello,computer print(s.isidentifier()) #输出为False&#xff0c;不是合法标识符&#xff0c;这是因为标识符是由字母&#xff0c;数字&#xff0c;下划线组成&#…

安卓调用手机邮箱应用发送邮件

先来看看实现效果&#xff1a; 也不过多介绍了&#xff0c;直接上代码&#xff1a; private void openMail() {Uri uri Uri.parse("mailto:" "");List<ApplicationInfo> applicationInfoList getPackageManager().getInstalledApplications(Packa…

DPU国产生态版图又双叒扩大了

DPU朋友圈迎来30新伙伴&#xff01;近期&#xff0c;中科驭数已与联想、中科可控、统信、欧拉、龙蜥社区、新支点、亚信科技、人大金仓、瀚高、南大通用、GreatSQL、阿里云、曙光云等超30家关键厂商完成兼容性互认证。测试报告显示&#xff0c;中科驭数DPU系列产品在产品兼容性…

好消息!2023年汉字小达人市级比赛在线模拟题大更新:4个组卷+11个专项,助力孩子更便捷、有效、有趣地备赛

自从《中文自修》杂志社昨天发通知&#xff0c;官宣了2023年第十届汉字小达人市级比赛的日期和安排后&#xff0c;各路学霸们闻风而动&#xff0c;在自己本就繁忙的日程中又加了一项&#xff1a;备赛汉字小达人市级比赛&#xff0c;11月30日&#xff0c;16点-18点。 根据这几年…

ChatGPT只算L1阶段,谷歌提出AGI完整路线图

按照谷歌这个标准来看&#xff0c;大多数已有AI产品其实都分别进入了不同的AGI阶段&#xff0c;但只仅限于在技能水平上——要谈及通用性&#xff0c;目前只有ChatGPT等模型完全合格。 AGI应该如何发展、最终呈什么样子&#xff1f; 现在&#xff0c;业内第一个标准率先发布&a…

春秋云境靶场CVE-2022-32991漏洞复现(sql手工注入)

文章目录 前言一、CVE-2022-32991靶场简述二、找注入点三、CVE-2022-32991漏洞复现1、判断注入点2、爆显位个数3、爆显位位置4 、爆数据库名5、爆数据库表名7、爆数据库数据 总结 前言 此文章只用于学习和反思巩固sql注入知识&#xff0c;禁止用于做非法攻击。注意靶场是可以练…

任意注册漏洞

目录 一漏洞介绍 二实战演示 三漏洞修复 本文由掌控安全学院 - 小博 投稿 一漏洞介绍 1.未验证邮箱/手机号 情景&#xff1a;应用为了方便用户记录用户名&#xff0c;使用邮箱和手机号作为用户名&#xff08;因此很多应用在注册的时候就要求用户填写&#xff0c;多数时候…

java spring cloud 企业电子招标采购系统源码:营造全面规范安全的电子招投标环境,促进招投标市场健康可持续发展

功能描述 1、门户管理&#xff1a;所有用户可在门户页面查看所有的公告信息及相关的通知信息。主要板块包含&#xff1a;招标公告、非招标公告、系统通知、政策法规。 2、立项管理&#xff1a;企业用户可对需要采购的项目进行立项申请&#xff0c;并提交审批&#xff0c;查看所…

vscode远程连接服务器报错

报错&#xff1a; Bad owner or permissions on C:\\Users\\Alice/.ssh/config> 过程试图写入的管道不存在。 1.ping一下config里面ip 2.ping的通&#xff0c;不是网络问题 3.扩展 -> remote-ssh -> 设置 -> 扩展设置&#xff08;红框&#xff09; 4.输入config绝…

后端接口性能优化分析-2

常见思路 1.批量思想&#xff1a; 这个其实是一个最容易想到的代码层次的修改&#xff0c;其实对业务上来说&#xff0c;结果都是一样的&#xff0c;只不过这个涉及到了一件事就是&#xff0c;像数据库中发请求&#xff0c;是发十次还是发一次的问题。其原因最根本的还是&…

评论:AlexNet和CaffeNet有何区别?

一、说明 在这个故事中&#xff0c;我们回顾了AlexNet和CaffeNet。AlexNet 是2012 年ILSVRC&#xff08;ImageNet 大规模视觉识别竞赛&#xff09;的获胜者&#xff0c;这是一项图像分类竞赛。而CaffeNet是AlexNet的单GPU版&#xff0c;因此&#xff0c;我们平时在普通电脑的Al…

一文懂得电源模块过温保护测试方法 ate测试软件助力测试

过温保护测试是电源模块保护功能测试项目之一&#xff0c;也是电源模块测试的重要测试指标&#xff0c;以保证电源模块过温保护功能正常&#xff0c;确保电源模块不受损坏。用ate测试软件测试电源模块过温保护&#xff0c;不仅可以保证测试结果的准确性&#xff0c;还可以多维度…

revit获取FamilySymbol的name

因为想解析把Element的CategoryId跟FamilySymbolId解析并存下来&#xff0c;这样就可以还原Revit中项目浏览器&#xff0c;里面的族的结构层次了。 参考&#xff1a;Revit中“Category、Family、 Familysymbol、 FamilyInstance”之间的关系​​​​​​ 但是对于wall和floor等…

通过key在数仓里查询dt的时候报错

现象 Query failed (#20231114_080638_00103_iaf4c) in hive: line 3:11: Column tyc_web_company_workright cannot be resolved 原因 key应该被单引号括起来&#xff0c;字段名称才应该被双引号括起来 修改 把单引号换成双引号就好了

软件测试自学指南,十年阿里测试工程师的建议

通过技能提升&#xff0c;入行IT可以的&#xff0c;但得先积累足够的经验&#xff0c;才能拿高薪&#xff0c;有个成长的过程。 软件测试岗介绍 软件测试岗位主要负责系统的测试工作&#xff0c;属于IT项目中的质量管理&#xff08;QA&#xff09;模块。 这个岗位分为两种类…

Python+Appium自动化测试框架详解

appium简介 Appium 是一个开源的、跨平台的测试框架&#xff0c;可以用来测试 Native App、混合应用、移动 Web 应用&#xff08;H5 应用&#xff09;等&#xff0c;也是当下互联网企业实现移动自动化测试的重要工具。Appium、Appium-desktop、Appium Client 的区别是 Appium …

识别代理IP:保障网络安全的重要一环

在互联网的世界中&#xff0c;代理服务器被广泛用于隐藏用户真实IP地址&#xff0c;带来了一些挑战&#xff0c;特别是在网络安全和欺诈检测方面。本文将探讨如何识别代理IP&#xff0c;以确保网络的安全性和可靠性。 1. 代理IP的背景与用途 代理服务器是位于用户和目标服务器…