拖放具体分为以下几个事件:
QEvent::DragEnter
当拖动文件进入到窗口/控件中时,触发该事件,它对应的子类是QDragEnterEventQEvent::DragLeave
当拖动文件离开窗口/控件时,触发该事件,它对应的子类是QDragLeaveEventQEvent::DragMove
当拖动文件在窗口/控件中移动时,触发该事件,它对应的子类是QDragMoveEventQEvent::Drop
当拖动文件在窗口/控件中释放时,触发该事件,它对应的子类是QDropEvent
本节通过一个向QTextEdit中拖放文本文件的案例,来讲解拖放事件
1. 自定义控件TextEditX
自定义一个标签控件TextEditX,让它继承自QTextEdit,然后重写拖放相关的函数。
1.1 添加 TextEditX 类
首先,在左侧项目文件名上右键,选择 “Add New…”,选择 “cpp Class”,先继承自QWidget,如下:
然后,把父类由QWidget修改为QTextEdit,如下:
// labelx.h
#include <QTextEdit>
class TextEditX : public QTextEdit {
Q_OBJECT
public:
explicit TextEditX(QWidget *parent = nullptr);
signals:
};
// labelx.cpp
#include "texteditx.h"
TextEditX::TextEditX(QWidget *parent) : QTextEdit{parent}
{
}
1.2 重写拖放函数
首先,来到textedit.h,声明4个拖放函数,如下::
#include <QDragEnterEvent>
#include <QDragLeaveEvent>
#include <QDragMoveEvent>
#include <QDropEvent>
class TextEditX : public QTextEdit {
protected:
void dragEnterEvent(QDragEnterEvent *e);
void dragMoveEvent(QDragMoveEvent *e);
void dragLeaveEvent(QDragLeaveEvent *e);
void dropEvent(QDropEvent *e);
};
然后,来到textedit.cpp 实现这4个函数(这里仅仅是加一句打印):
TextEditX::TextEditX(QWidget *parent) : QTextEdit{parent}
{
this->setAcceptDrops(true);
}
void TextEditX::dragEnterEvent(QDragEnterEvent *e)
{
qDebug() << "dragEnterEvent";
// 判断是正常的文件,表明用户可以在这个窗口部件上拖放对象。
// 默认情况下,窗口部件是不接受拖动的。Qt会自动改变光标来向用户说明这个窗口部件是不是有效的放下点
e->acceptProposedAction();
}
void TextEditX::dragMoveEvent(QDragMoveEvent *e)
{
qDebug() << "dragMoveEvent";
}
void TextEditX::dragLeaveEvent(QDragLeaveEvent *e)
{
qDebug() << "dragLeaveEvent";
}
void TextEditX::dropEvent(QDropEvent *e)
{
qDebug() << "dropEvent";
}
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);
}
此时,运行程序并拖放一个文本文件到TextEditX中,可以看到控制台依次打印如下:
2. 实现打开文件功能
只需修改dropEvent() 函数,如下:
#include <QFile>
#include <QMimeData>
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(),如下:
class TextEditX : public QTextEdit
{
protected:
void wheelEvent(QWheelEvent* e);
};
然后,实现wheelEvent()函数:
#include <QApplication>
void TextEditX::wheelEvent(QWheelEvent *e)
{
// 可以通过angleDelta()方法来判断滚轮的滚动方向。
// angleDelta()返回一个QPoint对象,其中x()表示水平滚动的角度,y()表示垂直滚动的角度。
// 通常,我们主要关注垂直滚动方向。
if (QApplication::keyboardModifiers() == Qt::ControlModifier) { // ctrl键的判断
if (e->angleDelta().y() > 0) { // scroll up
this->zoomIn();
} else { // scroll down
this->zoomOut();
}
}
QTextEdit::wheelEvent(e); // 调用基类的 wheelEvent 处理函数,确保其他默认行为正常
}





