QT拖拽功能简介

Qt Drag&Drop拖动与放置 本文章从属于系列拖放操作包括两个动作:拖动(drag)和放下(drop或称为放置)。 阅读详情
Drag 和Drop是两个完全不同的动作。Qt中的控件可以作为拖动(drag)的地点,也可以作为松开(drop)的地点,或者同时作为拖动和松开的地点。
第一个例子用来说明一个Qt应用程序接受另一个程序触发的拖动事件。该Qt应用程序是一个QTextEdit为中央控件的主窗口。当用户从桌面或者一个文件浏览器中拖动一个文本文件到Qt程序时松开,程序把文件显示在QTextEdit控件中。
下面是主窗口的定义
class MainWindow : public QMainWindow
{
    Q_OBJECT
public:
    MainWindow();
protected:
    void dragEnterEvent(QDragEnterEvent *event);
    void dropEvent(QDropEvent *event);
private:
    bool readFile(const QString &fileName);
    QTextEdit *textEdit;
};
 
在MainWindow类中,重新实现了QWidget的函数dragEnterEvent()和dropEvent()。由于这个例子主要用来显示托拽,主窗口的很多其他功能都省略了。
 
MainWindow::MainWindow()
{
    textEdit = new QTextEdit;
    setCentralWidget(textEdit);
    textEdit->setAcceptDrops(false);
    setAcceptDrops(true);
    setWindowTitle(tr("Text Editor"));
}
 
在构造函数中,我们创建了一个QTextEdit控件,并设置为中央控件。缺省情况下,QTextEdit接受来自其他应用程序拖拽来的文本,把文件名显示出来。由于drop事件是由子控件向父控件传播的,通过禁止QTextEdit控件的drop事件,允许主窗口得到drop事件,我们就得到了MainWindow中的整个窗口的drop事件。
void MainWindow::dragEnterEvent(QDragEnterEvent *event)
{
    if (event->mimeData()->hasFormat("text/uri-list"))
        event->acceptProposedAction();
}
 
任何时候用户拖动一个对象到一个控件上,函数dragEnterEvent()都会被调用。如果在这个事件处理函数中调用函数acceptProposeAction(),说明我们允许用户把这个对象拖拽到这个控件上。默认情况,控件不接收drag事件。Qt会自动改变光标状态指示用户当前的控件是否是一个合法的drop地点。
在这里我们只允许用户drag一个文本文件,因此,我们检查这个这个drag的MIME类型。MIME类型text/uri-list用来保存URL的一个地址列表,可以是文件名,URL(HTTP或者FTP路径),也可以是其他的全局资源标识。标准的MIME类型由IANA(Internet Assigned Numbers Authority)定义,由一个类型名/子类型名组成。MIME类型用于在剪贴板和拖拽使用时区别不同的数据类型,MIME类型列表可以点击访问http://www.iana.org/assignments/media-types/得到
void MainWindow::dropEvent(QDropEvent *event)
{
    QList<QUrl> urls = event->mimeData()->urls();
    if (urls.isEmpty())
       return;
    QString fileName = urls.first().toLocalFile();
    if (fileName.isEmpty())
        return;
    if (readFile(fileName))
        setWindowTitle(tr("%1 - %2").arg(fileName)
                                    .arg(tr("Drag File")));
}
 
当用户将一个对象放在控件上drop时,函数dropEvent()就会调用。QMineData::urls()得到一个QUrls列表。通常用户一次只会拖动一个文件,但是拖动多个文件也是允许的。如果用户拖动了多个URLs,或者URL不是一个文件名,程序立即返回。
QWidget 还提供了dragMoveEvent()和dragLeaveEvent(),但是对于大多数应用程序,这两个函数都不需要重写。
第二个例子来说明怎样进行drag,怎样接受drop。我们将会创建一个QListWidget子类,它可以接受drag和drop。并把它作为Project Choonser 程序的一个组件,如9.1所示:
Figure 9.1. The Project Chooser application
Project Chooser 程序由两个名字列表控件组成。每一个列表控件表示一个项目。用户可以drag和drop列表中的名字,把一个名字从一个项目移到另一个项目中。
在列表控件的子类中实现了drag和drop部分的代码。下面是类的定义:
class ProjectListWidget : public QListWidget
{
    Q_OBJECT
public:
    ProjectListWidget(QWidget *parent = 0);
protected:
    void mousePressEvent(QMouseEvent *event);
    void mouseMoveEvent(QMouseEvent *event);
    void dragEnterEvent(QDragEnterEvent *event);
    void dragMoveEvent(QDragMoveEvent *event);
    void dropEvent(QDropEvent *event);
private:
    void startDrag();
    QPoint startPos;
};
该类重新实现了5个QWidget中声明的事件处理函数。  
ProjectListWidget::ProjectListWidget(QWidget *parent)
    : QListWidget(parent)
{
    setAcceptDrops(true);
}
在构造函数中,我们让列表控件允许接受drop。
 
void ProjectListWidget::mousePressEvent(QMouseEvent *event)
{
    if (event->button() == Qt::LeftButton)
        startPos = event->pos();
    QListWidget::mousePressEvent(event);
}
当用户点击了鼠标左键时,我们把鼠标位置保存在startPos变量中。然后调用基类QListWidget的mousePressEvent(),使QListWidget能处理鼠标点击事件,即列表控件的鼠标点击事件进入程序的消息循环。
 
void ProjectListWidget::mouseMoveEvent(QMouseEvent *event)
{
    if (event->buttons() & Qt::LeftButton) {
        int distance = (event->pos() - startPos).manhattanLength();
        if (distance >= QApplication::startDragDistance())
            startDrag();
    }
    QListWidget::mouseMoveEvent(event);
}
如果用户按住鼠标左键同时移动鼠标,把这个过程认为是一个drag。计算当前鼠标位置和鼠标第一次点击的位置之间的距离,如果这个距离大于QApplication认定的拖动的最小距离(通常为四个象素),调用私有函数startDrag()开始拖动。通过判断距离可以避免因为用户手抖动引起的误操作。
 
void ProjectListWidget::startDrag()
{
    QListWidgetItem *item = currentItem();
    if (item) {
        QMimeData *mimeData = new QMimeData;
        mimeData->setText(item->text());
        QDrag *drag = new QDrag(this);
        drag->setMimeData(mimeData);
        drag->setPixmap(QPixmap(":/images/person.png"));
        if (drag->start(Qt::MoveAction) == Qt::MoveAction)
            delete item;
    }
}
在startDrag()中,我们创建一个QDrag对象,this指针表示父类为当前的列表控件ProjectListWidget。QDrag对象保存了一个QMimeData对象中的数据。在这个例子中,我们只是使用QMimeData::setText()保存了一个text/plain 串。QMimeData提供了很多函数处理经常用到的拖动类型(如图像,URLs,颜色等等),对于用QByteArrays表示的任意MIME类型都可以处理。当drag发生时,函数QDrag::setPixmap()设置了跟随鼠标的图标。
调用QDrag::start()开始拖动,直到用户drop或者取消了拖动。函数的参数为多个“drag actions”的组合(Qt::CopyAction, Qt::MoveAction, Qt::LinkAction)。返回值为执行拖动的“drag action”,如果没有执行拖动的操作,则返回Qt::IgnoreAction。具体执行哪个action取决于源控件允许的操作,目标控件允许的操作和drop的同时是否有附加键按下。调用start()后,Qt拥有被拖动的对象,在不需要时将其删除。
void ProjectListWidget::dragEnterEvent(QDragEnterEvent *event)
{
    ProjectListWidget *source =
            qobject_cast<ProjectListWidget *>(event->source());
    if (source && source != this) {
        event->setDropAction(Qt::MoveAction);
        event->accept();
    }
}
ProjectListWidget 不但可以产生drag,还可以接受来自程序中其他ProjectListWidget控件的drag。如果drag发生在同一个应用程序中,QDragEnterEvent::source()得到产生drag控件的指针。如果不是一个程序,则返回空指针。qobject_cast<T>()可以确保拖动来自与一个ProjectListWidget控件。如果一切正常,则调用accept()通知Qt接受这个action作为一个移动操作
 
void ProjectListWidget::dragMoveEvent(QDragMoveEvent *event)
{
    ProjectListWidget *source =
            qobject_cast<ProjectListWidget *>(event->source());
    if (source && source != this) {
        event->setDropAction(Qt::MoveAction);
        event->accept();
    }
}
函数dragMoveEvent()和dragEnterEvent()的代码是相同的。这有必要,因为需要覆盖QListWidget的(实际上是QAbstractItemView的)函数实现。
 
void ProjectListWidget::dropEvent(QDropEvent *event)
{
    ProjectListWidget *source =
            qobject_cast<ProjectListWidget *>(event->source());
    if (source && source != this) {
        addItem(event->mimeData()->text());
        event->setDropAction(Qt::MoveAction);
        event->accept();
    }
}
在dropEvent()中,调用QMimeData::text()得到拖动的文本,并用这个文本创建一个列表项目。我们还需要调用event->setDropAction(Qt::MoveAction),用参数Qt::MoveAction通知源控件可以删除原来拖动的项目。
在程序间需要转移数据时,拖拽是一个非常有用的机制。但是有时候不用拖拽机制也可以实现拖拽同样的操作。如果我们只是想在同一个程序同一个控件中移动数据,只需要重写mousePressEvent()和mouseReleaseEvent()就可以。
Qt编写可拖拽的自定义控件 qt实现的可自定义拖拽控件 阅读详情

相关推荐

【Qt】Qt中的拖放操作实现——拖放文件以及自定义拖放操作

实现Qt中的拖放操——拖放文件以及自定义拖放操作

sinat_41752325的博客 8339

【QT】QT的dragEnterEvent和dropEvent事件失灵解决办法

QT的dragEnterEvent和dropEvent事件失灵解决办法

你能行_的博客 1万+

AT32F403A ADC通道管理与转换模式实战解析

本文深入解析AT32F403A微控制器的ADC模块,重点阐述其通道管理机制与四种转换模式(序列模式、抢占自动转换模式、反复模式、分割模式)的实战应用。通过详细的配置步骤与代码示例,帮助开发者高效实现模拟数字转换,优化数据采集性能与系统响应。

sky77的博客 279

Qt拖放事件与拖放操作笔记dragEnterEvent,dropEvent

拖放事件主要用于处理MIME数据,该数据是用于在发送电子邮件时,附加多媒体数据(即拖拽一个文件放入邮件中,事件文件的上传)。

lucust的博客 1216

NOAA气象数据下载攻略

各方搜寻气象数据下载途径,发现网上最多的就是从NOAA下载,但是中途有尝试过很多次都没有下载到,每次都是显示不可用,今天终于下载成功了,特此记录。 首先我是从这个网址进入的:National Centers for Environmental Information (NCEI) formerly known as National Climatic Data Center (NCDC) | NCEI offers access to the most significant archives of oc

lianqian66的博客 3万+

xsens IMU配置

1.安装驱动 sudo apt-get update sudo apt-get install ros-kinetic-xsens-driver 2.配置IMU 设置输出四元数,加速度、角速度、地磁 cd /opt/ros/kinetic/lib/xsens_driver python mtdevice.py --configure "oq,aa,wr,mf" 3.启动IMU roslaunch xsens_driver xsens_driver.launch 转(https://www.cnblo

qq_41585680的博客 2325

QT鼠标拖拽功能简介

Drag和Drop是两个完全不同的动作。Qt中的控件可以作为拖动(drag)的地点,也可以作为松开(drop)的地点,或者同时作为拖动和松开的地点。 第一个例子用来说明一个Qt应用程序接受另一个程序触发的拖动事件。该Qt应用程序是一个QTextEdit为中央控件的主窗口。当用户从桌面或者一个文件浏览器中拖动一个文本文件到Qt程序时松开,程序把文件显示在QTextEdit控件中。 下面是主窗口的

fqx111的专栏 4981

MCU启动流程详解

在MCU启动后,系统从flash主存储区开始执行,先将0x08000000地址存放的堆栈栈顶指针赋给SP寄存器,将0x08000004地址存放的Reset_Handler复位向量地址赋给PC寄存器跳转执行系统复位,期间执行System_Initializes函数配置系统时钟,重定位向量表,执行MDK自带库函数__main将RW、ZI数据段从Flash加载到RAM,并跳转至_rt_entry进行Stack和Heap的初始化,最后跳转到熟悉的main函数。

weixin_50827397的博客 1505

QT拖拽打开功能简介

原文转载于:https://blog.youkuaiyun.com/pcsuite/article/details/6147191Drag和Drop是两个完全不同的动作。Qt中的控件可以作为拖动(drag)的地点,也可以作为松开(drop)的地点,或者同时作为拖动和松开的地点。第一个例子用来说明一个Qt应用程序接受另一个程序触发的拖动事件。该Qt应用程序是一个QTextEdit为中央控件的主窗口。当用户从桌面...

农村的我的专栏 1239

Ubuntu 22.04 LTS下Xenomai 3.3实时内核配置全攻略(附常见错误排查)

本文详细介绍了在Ubuntu 22.04 LTS系统上配置Xenomai 3.3实时内核的完整流程,包括环境准备、内核补丁应用、编译优化及常见错误排查。特别针对工业自动化和机器人控制场景,提供了性能优化建议和故障解决方案,帮助开发者实现毫秒级精度的实时任务处理。

weixin_29268385的博客 464

微信小程序OCR身份证识别实战:从拍照到信息提取全流程解析

本文详细解析了微信小程序中OCR身份证识别的全流程实现,从环境配置、拍照上传到OCR核心识别及安全优化。通过微信开发者工具和OCR插件,开发者可快速构建高效的身份信息采集系统,提升用户体验和数据安全性。重点介绍了图像处理、加密传输及混合云架构等企业级解决方案。

j0k1l2m3n的博客 458

QTableViewMoveAction 源码下载

QTableViewMoveAction 源码下载 【下载地址】QTableViewMoveAction源码下载 QTableViewMoveAction是一个基于Qt框架的开源项目,提供了QTableView控件中拖拽交换行、列和单元格的完整源码。通过简单的拖拽操作,用户可以轻松调整表格中元素的位置,极大提升了用户体验...

gitblog_06740的博客 391

【福建dem】原始高程数据tif格式

DEM(Digital Elevation Model,数字高程模型)是一种地理信息系统中的关键数据集,它提供了地表地形的三维信息,通常用于分析地貌特征、模拟水文过程、规划建设、灾害预警等多个领域。这种数据对于地理分析非常有价值,例如,它可以用于计算坡度、坡向、地形粗糙度等地形特征,或者进行洪水模拟、地质灾害评估、太阳能辐射分析等。“福建dem原始高程数据tif格式”是研究和理解福建省地形地貌的重要资源,结合GIS工具,可以揭示丰富的地理信息,为科研、工程和决策提供有力支持。

鸿业远图科技 943

Qt中自定义QTreeWidget实现节点拖拽复制功能

QT中在QWidget支持拖拽功能,QTreeWidget继承自QWidget,所以自然也具有节点的拖拽功能。 拖拽包含两个功能:一个是拖动(Drag),一个是放下(Drop)。拖动的数据是QMimeData数据,MIME数据定义格式:类型/数据 (注意中间有斜线)。 若被拖动的对象放下的控件,不接受拖动的对象,Qt光标显示禁用的形状(一个禁用形状)。 开始拖动:通过调用QDrag::exec()...

wb175208的专栏 6171

模组 RG500Q入网问题分析

- [ ] 不同于公网,在5G专网环境中, 通常使用很多非标准的网络配置,如PLMN/APN等。因此,5G模组在专网环境下通常要做一些专门的配置才能正常入网,本文分析一例在专网环境, 5G终端无法入网问题的定位过程。 - [ ] 具体涉及到以下模组操作: 恢复出厂、SA only、锁BAND、配置MBN等

十年通信老兵的技术修炼之路——从3G到5G,从地面基站到卫星通信。 935

pscad IEEE标准系统搭建说明

pscad IEEE标准系统搭建说明,包含典型的IEEE 9节点、14节点、30节点、39节点和118节点系统。内含标准测试系统的原始数据和潮流结果。

【Qt】Qt拖拽功能实现

拖拽流程阶段,启动拖拽(Drag Initiation):用户按下鼠标并移动(通常是左键按下后移动)。数据传输(Data Transfer):通过`QMimeData`封装数据(如文本、图像、自定义二进制数据)。目标接受(Drop Target):控件检测到拖拽进入时决定是否接受数据。数据处理(Data Handling):目标控件解析数据并完成操作(如添加项、移动文件)。

weixin_43510208的博客 1752

IMSL CNL 7.0.0 (x86-64)Crack

IMSL CNL 7.0.0 (x86-64)Crack intel的算法库破解文件,这是C++版本的破解文件

QT的拖拽功能

QT的拖拽功能介绍与案列

weixin_44840658的博客 1403

计算机控制技术及应用

《计算机控制技术及应用》通过总结作者的科研成果和吸收国内外的先进理论、方法和技术,以计算机控制系统的网络化、开放化、智能化和集成化发展趋势为主线索,主要介绍计算机控制系统的基本概念和计算机控制系统的典型形式,计算机控制系统的数学描述与基本分析方法,以及数字PID控制器、最少拍控制系统、达林算法、状态变量设计法等设计方法及其各种改进算法。重点突出计算机控制系统输入输出通道接口的设计方法和典型控制系统的设计案例与实现方法等。

最新的sdio 4.0 spec 协议标准 带书签 高清完整PDF版

Part-E1-SDIO-Specification-Ver4.00-Final-120220.pdf:最新的sdio 4.0 spec 协议标准 带书签 高清完整PDF版,包括SDIO 接口的外设,SDIO 接口官方协议等。

Qt Drag and Drop 实现拖拽控件效果

#在头文件中声明事件操作函数,MainWindow.h中如下: #ifndef MAINWINDOW_H #define MAINWINDOW_H #include <QMainWindow> QT_BEGIN_NAMESPACE namespace Ui { class MainWindow; } QT_END_NAMESPACE class MainWindow : publ...

ASCE_Python的博客 4883

qt中的拖拽及其使用技巧

关于qt中的拖放操作,首先可以看这篇官方文档:http://doc.qt.io/qt-5.5/dnd.html 一、QDrag 首先是创建QDrag,可以在mousePressEvent或者mouseMoveEvent中创建。 void DragDropWidget::mousePressEvent(QMouseEvent *event) { if (event->butto...

vvsxr的专栏 3万+

Qt 之 简单截图功能(三)实现可拖拽选中区域

一、简述在 Qt 之 简单截图功能(一)实现鼠标选中区域截图 、 Qt 之 简单截图功能(二)实现可移动选中区域 中简单叙述了实现截图功能的两小步,今天第三篇来实现可拖拽选中矩形顶点进行重新选择截图区域,话不多说先看效果图,再上代码。效果图:二、代码之路这一篇中将实现实现如何通过鼠标拖拽重新选取截图区域。代码可能稍长,整体代码是在前两篇的基础上完善的,建议先从 Qt 之 简单截图功能(一)实现鼠标选......

前行之路还需前行 1万+

QT上实现文件拖拽功能

转自于QT上实现文件拖拽功能 声明dragEnterEvent和dropEvent事件函数,对窗口的拖拽行为进行处理 // 由MainWindow来截取拖拽事件 ①ui->lineEdit->setAcceptDrops(false); ②this->setAcceptDrops(true); 注: 第①很关键,笔者在Linux和Windows用相同的代码出现了一个小bug...

Linux Openharmony Android Graphics Stack! 4300
上一篇: QT调用CHM方法
下一篇: STL几种容器的区别简介
pcsuite
博客等级 码龄16年 35粉丝 16原创
评论 8
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

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

抵扣说明:

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

余额充值