首页 > 其他分享 >Qt拖拽事件详解,拖放数据传递

Qt拖拽事件详解,拖放数据传递

时间:2024-09-20 17:24:10浏览次数:8  
标签:mimeData Qt DragTreeView 拖拽 Drag include event 拖放

1.QT拖拽事件分为两类。

(1)电脑上的文件拖入程序,在程序上放下文件Drop;例如将视频拖入程序进行播放,将图片突入程序进行展示;

(2)程序中界面内部拖放,例如将组织树中的监控点拖入播放窗口进行播放;将一个表格中的人员拖入另外一个表格等;将QTreeview中的item拖动位置,移到不同的组织下;或者将QTableView中item上下移动位置,调整顺序;

2.Qt拖拽类型

(1)复制,源不变,复制一个新的到指定位置;

(2)移动,源删除,将目标移动到新的位置;

3.实现方案

从电脑中拖拽的示例的可以参考https://www.cnblogs.com/bclshuai/p/18320512,本文中主要讲从左侧QTreeView中拖拽一个监控点或者组织去右侧播放窗口去播放;

3.1识别拖的动作,并设置数据到QMimeData

继承QTreeView,重写mousePressEvent函数和mouseMoveEvent函数;mousePressEvent感知鼠标按下操作,结合mouseMoveEvent,当鼠标按下左键,同时移动距离大于系统的拖拽移动距离,表示拖动,很多人在鼠标按下时就创建QDrag对象,这是不对的;应该是要拖动;才触发QDrag;

#ifndef DRAGTREEVIEW_H
#define DRAGTREEVIEW_H

#include <QTreeView>
#include <QMouseEvent>
#include <QPoint>
class DragTreeView : public QTreeView
{
    Q_OBJECT

public:
    DragTreeView(QWidget *parent);
    ~DragTreeView();
    void mousePressEvent(QMouseEvent *event);
    void mouseMoveEvent(QMouseEvent *event);
private:
    QPoint m_dragStartPos;
    QModelIndex m_currentIndex;
};

#endif // DRAGTREEVIEW_H
#include "DragTreeView.h"
#include <QApplication>
#include <QLine>
#include <QMimeData>
#include <QDrag>
#include "hlog1.h"
DragTreeView::DragTreeView(QWidget *parent)
    : QTreeView(parent)
{

}

DragTreeView::~DragTreeView()
{

}

void DragTreeView::mousePressEvent(QMouseEvent *event)
{
    if (event->button() == Qt::LeftButton) {
        QPoint pos = event->pos();
        m_currentIndex = indexAt(pos);
        if (m_currentIndex.isValid())
        {
            m_dragStartPos = pos;
        }
    }
    QTreeView::mousePressEvent(event);
}

void DragTreeView::mouseMoveEvent(QMouseEvent *event)
{
    if (event->buttons() & Qt::LeftButton) 
    {
        int distance = (event->pos() - m_dragStartPos).manhattanLength();//计算距离
        int distance2 = QLineF(event->pos(), m_dragStartPos).length();//方式2计算距离
        if (distance >= QApplication::startDragDistance()) {
            //触发QDrag操作
            m_currentIndex = currentIndex();
            if (m_currentIndex.isValid())
            {
                QVariantMap valu = m_currentIndex.data(Qt::UserRole).toMap();
                QString strType = valu.value("type").toString();
                QMimeData *mimeData = new QMimeData;
                if (strType=="3")//拖放监控点播放,传入监控点id
                {
                    mimeData->setData("Drag/Camera", valu.value("channel_id").toString().toStdString().c_str());
                } 
                else if (strType == "1")//拖拽组织进行播放,传入组织id
                {
                    mimeData->setData("Drag/Group", valu.value("id").toString().toStdString().c_str());
                }
                
                LOG_INFO("mouse move");
                QDrag *drag = new QDrag(this);
                drag->setMimeData(mimeData);
                drag->exec( Qt::MoveAction);//阻塞住,mouseMoveEvent不会再次触发,QDrag不会重复创建;鼠标释放会结束消息
                delete drag;
                LOG_INFO("drag finish");
            }        
        }
    }
}

 

3.2放的时候,读取拖的时设置到QMimeData的数据

拖拽接收方一定要设置属性setAcceptDrops(true);否则无法接收拖放消息;实现dragEnterEvent函数,在dragEnterEvent中调用event->acceptProposedAction();否则dropEvent无法响应;

#include "deviceview.h"
#include "DbPlugin.h"
#include<QMimeData>
DeviceView::DeviceView(QWidget *parent)
    : QMainWindow(parent)
{
    ui.setupUi(this);
    if (DbPlugin::instance()->LoadDbPlugin()==-1)
    {
        LOG_ERROR("数据库插件加载失败");
    }
    m_pDeviceTree = new DeviceTree(ui.widgetLeft);
    ui.verticalLayout->addWidget(m_pDeviceTree);
}

DeviceView::~DeviceView()
{

}

void DeviceView::dragEnterEvent(QDragEnterEvent *event)//接收数据可用性判断,或者接收显示效果设置
{
    const QMimeData *mimeData = event->mimeData();
    int CountUnsurport = 0;
    QStringList listPath;
    if (ui.widgetRight->underMouse())
    {
        if (mimeData->hasFormat("Drag/Camera")|| mimeData->hasFormat("Drag/Group")) {
            event->acceptProposedAction(); // 接受拖动,一定要accept,否则dropEvent无法响应
        }
    }
    else
    {
        event->ignore(); // 接受拖动
    }
}

void DeviceView::dropEvent(QDropEvent *event)
{
    if (ui.widgetRight->underMouse())
    {
        const QMimeData *mimeData = event->mimeData();
        if (mimeData->hasFormat("Drag/Camera"))
        {
            QString channelid = event->mimeData()->data("Drag/Camera");
            //根据监控点id播放监控点
        }
        else if (mimeData->hasFormat("Drag/Group"))
        {
            QString groupid = event->mimeData()->data("Drag/Group");
            //根据组织播放多个监控点
        }    
    }
}

 

标签:mimeData,Qt,DragTreeView,拖拽,Drag,include,event,拖放
From: https://www.cnblogs.com/bclshuai/p/18422580

相关文章

  • 【qt】一个WPS项目了解qt界面设计的基本套路
    项目功能演示:放心食用!最后有完整代码.超级详细,期待您的一个点赞❥(^_-)一览全局:WPS项目目录一.创建项目二.导入资源三.ui设计四.字号选择框初始化五.滚动条初始化六.添加自定义文本类七.初始化action状态八.新建文档九.打开文件十.保存与另存为十一.打印/打......
  • PyQGIS开发 2 Qt开发入门
    PyQGISQt开发入门1使用QtDesignerQGIS在安装后已经配套了QtDesigner,可以在开始菜单->QGIS->QtDesignerforQGIS点击运行程序,或者在QGIS安装目录/bin/qgis-designer.bat(或qgis-ltr-designer.bat)点击运行。选择MainWindow模板创建,点击下方的创建后,将创建如......
  • QT Widgets模块源码解析与应用
    QTWidgets模块源码解析与应用使用AI技术辅助生成QT界面美化视频课程QT性能优化视频课程QT原理与源码分析视频课程QTQMLC++扩展开发视频课程免费QT视频课程您可以看免费1000+个QT技术视频免费QT视频课程QT统计图和QT数据可视化视频免费看免费QT视频课程QT性能优化视......
  • QT QML模块的编程挑战与解决方案
    QTQML模块的编程挑战与解决方案使用AI技术辅助生成QT界面美化视频课程QT性能优化视频课程QT原理与源码分析视频课程QTQMLC++扩展开发视频课程免费QT视频课程您可以看免费1000+个QT技术视频免费QT视频课程QT统计图和QT数据可视化视频免费看免费QT视频课程QT性能优化......
  • QT绘图模块与数据库的结合
    QT绘图模块与数据库的结合使用AI技术辅助生成QT界面美化视频课程QT性能优化视频课程QT原理与源码分析视频课程QTQMLC++扩展开发视频课程免费QT视频课程您可以看免费1000+个QT技术视频免费QT视频课程QT统计图和QT数据可视化视频免费看免费QT视频课程QT性能优化视频免......
  • PyQt5 中的强大工具 ——QTextEdit 富文本框
    在PyQt5的世界里,QTextEdit是一个功能强大的富文本框组件,它为开发者提供了丰富的文本编辑和展示功能。本文将深入探讨PyQt5中的QTextEdit,带你领略其强大之处。一、引言在现代图形用户界面(GUI)应用程序中,富文本编辑功能是不可或缺的一部分。无论是编写文档、编辑邮件还......
  • QT硬件性能优化
    QT硬件性能优化使用AI技术辅助生成1QT硬件性能优化概述1.1QT硬件性能优化的重要性1.1.1QT硬件性能优化的重要性QT硬件性能优化的重要性《QT硬件性能优化》正文,QT硬件性能优化的重要性在当今的数字时代,硬件性能对于应用程序的性能有着至关重要的影响。作为QT高级工......
  • QT硬件异构计算
    QT硬件异构计算使用AI技术辅助生成1QT硬件异构计算概述1.1硬件异构计算概念1.1.1硬件异构计算概念硬件异构计算概念《QT硬件异构计算》正文硬件异构计算概念在进入具体的硬件异构计算概念之前,我们首先需要理解什么是硬件异构。硬件异构是指在一个计算系统中,存在着不......
  • PyQt5 使用 QStackedWidget 实现轮播展示动画,但是却疯狂闪烁的解决办法
    PyQt5使用QStackedWidget实现轮播展示动画,但是却疯狂闪烁的解决办法上篇说到,上篇见这里我们可能会遇到,当把鼠标移动到"下一页"和"上一页"按钮,又或者是Qlabel标签页时,就会疯狂闪烁,于是在这里换另一种方案,解决这个问题代码结构本文基于上篇,上篇见这里修改而来,全部代码......
  • .NET 开源高性能 MQTT 类库
    目录前言项目介绍功能说明客户端功能服务器功能功能特点应用场景使用方法1、安装MQTTnet2、服务端代码3、客户端代码项目地址总结最后前言随着物联网(IoT)技术的迅猛发展,MQTT(消息队列遥测传输)协议凭借其轻量级和高效性,已成为众多物联网应用的首选通信标准。......