Day24QDragEvent拖放事件2021-12-02

  • Post author:
  • Post category:其他




Qt中的拖放事件



内容与场景

介绍Qt中的两个事件,拖动事件和拖放事件。其中拖动事件包括了在”拖住文件进入“、”拖住文件移动“、”拖住文件离开“三个事件。拖放事件指的是拖动文件到应用界面范围里,随后放开鼠标产生的事件。同时制作一个小场景学习,将图片拖入到界面中显示。场景中将用到拖动进度事件和拖放事件。



步骤

1.创建主界面。

使用栅格布局(底层代码记录产生了一个gridLayout)。

2.添加继承自QLabel的c++类myLabel。

a.重新实现dragEvent函数,在拖动进入事件的函数中获取”被拖入文件“的路径,并要使用

 event->accept();

写上这句之后,事件才会在事件过滤器中向下分发,否则无法无法dropevent事件

b.构造函数中需要添加

this->setAcceptDrops(true);


需要设置accepdrop属性,才能接收drop事件

c.重写dropevent函数,当”被拖入文件“被放下时,将其作为图片文件显示在Label中

3.在主界面中创建子类对象,并栅格布局子类对象。



注意

提醒注意的三个点是:

1.程序完成之后,拖入图片的路径中不能有中文,否则无法显示,当然其他类型的文件也不会被响应。

2.

this->setScaledContents(true);

此处的this代指的是自定的myLabel类对象lab。这个属性设置的含义是,当固定该label大小时例如,this->setFixedSize(400,400),启用这句话会自动的调整图片的大小适应控件的大小。若不固定控件大小,图片大就会把控件撑大,这句话也不能发挥作用。

3.事件函数的参数

对于常见的事件类型,当事件发生的时候,可以通过重写他相应的虚函数完成对该事件的处理,例如painter事件,鼠标事件等。这是事件发生后处理的一种方法,对于这种方法而言,当事件发生时,虚函数提供了”用户处理“的框架,虚函数的参数往往提供了系统在事件发生时保留的东西,以及一些对于事件过滤器的操作。例如,代码中

 QString path = event->mimeData()->text();

就是mimeData中的text方法能够返回被拖入文件的路径。当然就是系统在事件发生时,已经通过函数方法获取了文件的路径。



效果

在这里插入图片描述



代码

main

#include "widget.h"
#include <QApplication>
int main(int argc, char *argv[])
{
    QApplication a(argc, argv);
    Widget w;
    w.show();
    return a.exec();
}

widget.h代码

#ifndef WIDGET_H
#define WIDGET_H
#include <QWidget>
#include "mylabel.h"//添加子类头文件做引用
QT_BEGIN_NAMESPACE
namespace Ui { class Widget; }
QT_END_NAMESPACE
class Widget : public QWidget
{
    Q_OBJECT
public:
    Widget(QWidget *parent = nullptr);
    ~Widget();
private:
    Ui::Widget *ui;
    myLabel * lab;//创建子类对象
};
#endif // WIDGET_H

widget.cpp

#include "widget.h"
#include "ui_widget.h"
Widget::Widget(QWidget *parent)
    : QWidget(parent)
    , ui(new Ui::Widget)
{
    ui->setupUi(this);
    lab = new myLabel(this);//为子类对象分配空间
    lab->setText("Day 24");
    ui->gridLayout->addWidget(lab,0,0,1,1);//让lab栅格布局
}
Widget::~Widget()
{
    delete ui;
}

malabel.h

#ifndef MYLABEL_H
#define MYLABEL_H
//添加必要的头文件
#include <QWidget>
#include <QLabel>
#include <QDragEnterEvent>
#include <QDropEvent>
#include <QMimeData>
#include <QDebug>
class myLabel : public QLabel
{
    Q_OBJECT
public:
    explicit myLabel(QWidget *parent = nullptr);
    void dragEnterEvent(QDragEnterEvent *event);//重写拖动进入事件
    void dropEvent(QDropEvent *event);//重写拖放事件
signals:
private:
    QString filename;
};
#endif // MYLABEL_H

mylabel.cpp

#include "mylabel.h"

myLabel::myLabel(QWidget *parent) : QLabel(parent)
{
    filename.clear();
    this->setAcceptDrops(true);//不同于鼠标事件,必须设置这个属性,才能触发drop事件
    this->setFixedSize(400,400);
}
void myLabel::dragEnterEvent(QDragEnterEvent *event)
{
    QString path = event->mimeData()->text();//事件发生时,系统保存了他的路径
    if(filename.isEmpty())
    {
        filename = path;
    }
    else
    {
        if(filename!=path)
        {
            filename = path;
        }
    }
    event->accept();//写上这句之后,事件接收器接收这个事件,否则无法无法dropevent事件
}
void myLabel::dropEvent(QDropEvent *event)
{
    if(filename.isEmpty())
    {return;}
    else
    {
//        qDebug()<<filename;
//        路径为"file:///C:/Users/Jack_Chen/Desktop/Day24Test.png"
        filename.replace("file:///","");//去掉路径多余部分
        QPixmap pix(filename);
        this->setScaledContents(true);//当固定该label大小时this->setFixedSize(400,400);
        //启用这句话会自动的调整图片的大小适应空间的大小。若不固定控件大小,图片大就会把控件撑大
        this->setPixmap(pix);//见前面使用QLabel显示图片一节
        filename.clear();
    }
}