【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,如下:

cpp 复制代码
#include <QTextEdit>

class TextEditX : public QTextEdit
{
	// ...
};

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

cpp 复制代码
#include "texteditx.h"

TextEditX::TextEditX(QWidget* parent) : QTextEdit{parent}
{
}

1.2 重写拖放函数

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

cpp 复制代码
#include <QDragEnterEvent>
#include <QDragLeaveEvent>
#include <QDragMoveEvent>
#include <QDropEvent>

class TextEditX : public QTextEdit
{
protected:
    void dragEnterEvent(QDragEnterEvent* event);
    void dragMoveEvent(QDragMoveEvent* event);
    void dragLeaveEvent(QDragLeaveEvent* event);
    void dropEvent(QDropEvent* event);
};

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

cpp 复制代码
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.3 将 TextEditX 显示到界面

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

cpp 复制代码
#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);
}

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

2. 实现打开文件功能

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

cpp 复制代码
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());
    }
}

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

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

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

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

cpp 复制代码
class TextEditX : public QTextEdit
{
protected:
    void wheelEvent(QWheelEvent* e);
};

然后,实现 wheelEvent() 函数:

cpp 复制代码
#include <QApplication>

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);  // 调用父类的,否则无法实现文本的上下滚动。
    }
}

此时,运行效果如下:

相关推荐
灵性花火12 小时前
记录Qt的多个bug
qt·bug
Stanford_110613 小时前
关于嵌入式硬件需要了解的基础知识
开发语言·c++·嵌入式硬件·微信小程序·微信公众平台·twitter·微信开放平台
是那盏灯塔13 小时前
16.C++三大重要特性之多态
开发语言·c++
我是华为OD~HR~栗栗呀14 小时前
24届-Python面经(华为OD)
java·前端·c++·python·华为od·华为·面试
奥特曼狂扁小怪兽14 小时前
Qt 自定义无标题栏窗口:FramelessWidget 实现与解析
开发语言·qt
胖咕噜的稞达鸭15 小时前
缝合怪deque如何综合list和vector实现及仿函数模板如何优化priority_queue实现
数据结构·c++·算法·链表·list
tt55555555555515 小时前
C++ 经典数组算法题解析与实现教程
开发语言·c++·算法
泽虞15 小时前
《Qt应用开发》笔记
linux·开发语言·c++·笔记·qt
小邓儿◑.◑16 小时前
贪心算法 | 每周8题(二)
c++·算法·贪心算法
闻缺陷则喜何志丹16 小时前
【剪枝 贪心 回溯】B4093 [CSP-X2021 山东] 发送快递|普及+
c++·算法·剪枝·贪心·洛谷