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();
}
}