• 【QT开发笔记-基础篇】| 第四章 事件QEvent | 4.7 拖放事件


    本节对应的视频讲解:B_站_链_接

    QT开发笔记-基础篇】 第4章 事件 4.7 拖动事件


    本章要实现的整体效果如下:

    整体效果

    QEvent::DragEnter

    ​ 当拖动文件进入到窗口/控件中时,触发该事件,它对应的子类是 QDragEnterEvent

    QEvent::DragLeave

    ​ 当拖动文件离开窗口/控件时,触发该事件,它对应的子类是 QDragLeaveEvent

    QEvent::DragMove

    ​ 当拖动文件在窗口/控件中移动时,触发该事件,它对应的子类是 QDragMoveEvent

    QEvent::Drop

    ​ 当拖动文件在窗口/控件中释放时,触发该事件,它对应的子类是 QDropEvent

    本节通过一个向 QTextEdit 中拖放文本文件的案例,来讲解拖放事件


    1. 自定义控件 TextEditX

    自定义一个标签控件 TextEditX,让它继承自 QTextEdit,然后重写拖放相关的函数。

    1.1 添加自定义控件类 TextEditX

    首先,在左侧项目文件名上右键,然后选择 “添加新文件”,选择 “C++ Class”,如下:

    添加类

    新建类文件信息如下:

    文件信息


    然后,把父类修改为 QTextEdit

    来到 texteditx.h 将父类由 QWidget 修改为 QTextEdit,如下:

    #include 
    
    class TextEditX : public QTextEdit
    {
    	// ...
    };
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6

    来到 texteditx.cpp 将父类由 QWidget 修改为 QTextEdit,如下:

    #include "texteditx.h"
    
    TextEditX::TextEditX(QWidget* parent) : QTextEdit{parent}
    {
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5

    1.2 重写拖放函数

    首先,来到 textedit.h,声明这4个拖放函数:

    #include 
    #include 
    #include 
    #include 
    
    class TextEditX : public QTextEdit
    {
    protected:
        void dragEnterEvent(QDragEnterEvent* event);
        void dragMoveEvent(QDragMoveEvent* event);
        void dragLeaveEvent(QDragLeaveEvent* event);
        void dropEvent(QDropEvent* event);
    };
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13

    然后,来到 textedit.cpp 实现这4个函数(这里仅仅是加一句打印):

    TextEditX::TextEditX(QWidget* parent) : QTextEdit{parent}
    {
        this->setAcceptDrops(true);
    }
    
    void TextEditX::dragEnterEvent(QDragEnterEvent* event)
    {
        qDebug() << "dragEnterEvent";
    
        // 判断是正常的文件,表明用户可以在这个窗口部件上拖放对象。
        // 默认情况下,窗口部件是不接受拖动的。Qt会自动改变光标来向用户说明这个窗口部件是不是有效的放下点
        event->acceptProposedAction();
    }
    
    void TextEditX::dragMoveEvent(QDragMoveEvent* event)
    {
        qDebug() << "dragMoveEvent";
    }
    
    void TextEditX::dragLeaveEvent(QDragLeaveEvent* event)
    {
        qDebug() << "dragLeaveEvent";
    }
    
    void TextEditX::dropEvent(QDropEvent* event)
    {
        qDebug() << "dropEvent";
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28

    1.3 将 TextEditX 显示到界面

    来到 drag_widget.cpp,在构造函数中添加 TextEditX 控件,如下:

    #include "texteditx.h"
    
    DragWidget::DragWidget(QWidget* parent) : QWidget{parent}
    {
        QVBoxLayout* verticalLayout = new QVBoxLayout(this);
        verticalLayout->setSpacing(0);
        verticalLayout->setContentsMargins(10, 10, 10, 10);
    
        // 添加一个TextEdit
        TextEditX* textEdit = new TextEditX(this);
        textEdit->setPlaceholderText("支持文件拖放的方式,来打开文件");
        verticalLayout->addWidget(textEdit);
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13

    此时运行程序,效果如下:

    添加到界面


    2. 实现打开文件功能

    只需修改 dropEvent() 函数,如下:

    void TextEditX::dropEvent(QDropEvent* event)
    {
        qDebug() << "dropEvent";
        QList<QUrl> urls = event->mimeData()->urls();
        if ( urls.isEmpty() ) {
            return;
        }
    
        QString fileName = urls.first().toLocalFile();
        qDebug() << urls.first() << " : " << fileName;
    
        QFile file(fileName);
        if ( file.open(QIODevice::ReadOnly) ) {
            setPlainText(file.readAll());
        }
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16

    拖放一个桌面文件到 TextEditX 中,效果如下:

    文件打开功能


    3. 实现鼠标滚轮放大字体

    以上在 TextEditX 中显示的文本,字体大小固定,接下来实现,通过鼠标滚轮来设置字体大小

    首先,在 texteditx.h 中,声明鼠标滚轮滚动的事件 wheelEvent(),如下:

    class TextEditX : public QTextEdit
    {
    protected:
        void wheelEvent(QWheelEvent* e);
    };
    
    • 1
    • 2
    • 3
    • 4
    • 5

    然后,实现 wheelEvent() 函数:

    #include 
    
    void TextEditX::wheelEvent(QWheelEvent* e)
    {
        if ( QApplication::keyboardModifiers() == Qt::ControlModifier ) {  // ctrl键的判断
            // zoomIn/zoomOut可以直接修改字体大小
            if ( e->delta() > 0 ) {  // 滚轮远离使用者, 进行放大
                this->zoomIn();
            } else {
                this->zoomOut();  // 进行缩小
            }
    
        } else {
            QTextEdit::wheelEvent(e);  // 调用父类的,否则无法实现文本的上下滚动。
        }
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16

    此时,运行效果如下:

    最终效果

  • 相关阅读:
    C# OpenVINO 通用OCR识别 文字识别 中文识别 服务
    Python之并发编程(进程)
    LVS简介【暂未完成(半成品)】
    五分钟k8s入门到实战-应用配置
    day25--Java集合08
    HTML学生个人网站作业设计——中华美食(HTML+CSS) 美食静态网页制作 WEB前端美食网站设计与实现
    缓存一致性解决方案——改数据时如何保证缓存和数据库中数据的一致性
    解释 Git 的基本概念和使用方式。
    StarRocks从入门到精通系列三:创建表和导入和查询数据
    GitLab CI/CD系列教程(七):gitlab变量
  • 原文地址:https://blog.csdn.net/bili_mingwang/article/details/133898009