开发环境Qt5.9
先给出头文件代码如下:
#ifndef MAINWINDOW_H #define MAINWINDOW_H #include <QMainWindow> #include <QListWidget> #include <QtGui> class MainWindow : public QMainWindow { Q_OBJECT public : MainWindow ( QWidget * parent = 0 ) ; ~ MainWindow ( ) ; protected : void dragEnterEvent ( QDragEnterEvent * event = NULL ) ; void dropEvent ( QDropEvent * event = NULL ) ; private : QFileInfoList GetAllFileList ( QString filePath ) ; private : QListWidget * listWidget ; } ; #endif // MAINWINDOW_H
#include "mainwindow.h" MainWindow :: MainWindow ( QWidget * parent ) : QMainWindow ( parent ) { listWidget = new QListWidget ( ) ; //创建textEdit setCentralWidget ( listWidget ) ; //设置为中央窗口部件 listWidget -> setAcceptDrops ( false ) ; //设置textEdit禁用拖动 setAcceptDrops ( true ) ; //设置窗口启用拖动 setWindowTitle ( tr ( "Load File" ) ) ; } MainWindow :: ~ MainWindow ( ) { } void MainWindow :: dragEnterEvent ( QDragEnterEvent * event ) { if ( event -> mimeData ( ) -> hasFormat ( "text/uri-list" ) ) { event -> acceptProposedAction ( ) ; } } void MainWindow :: dropEvent ( QDropEvent * event ) { //窗口部件放下一个对象时,调用该函数 QList < QUrl > urls = event -> mimeData ( ) -> urls ( ) ; if ( urls . isEmpty ( ) ) { return ; } QList < QUrl > :: iterator it ; for ( it = urls . begin ( ) ; it != urls . end ( ) ; it ++ ) { QUrl url = * it ; QFileInfo fileInfo ( it -> toLocalFile ( ) ) ; if ( fileInfo . isFile ( ) ) { //是文件就直接加进来 listWidget -> addItem ( fileInfo . filePath ( ) ) ; } else if ( fileInfo . isDir ( ) ) { //文件路径就循环读取 QFileInfoList fileInfoList = GetAllFileList ( fileInfo . filePath ( ) ) ; for ( QFileInfo fileInfo1 : fileInfoList ) { listWidget -> addItem ( fileInfo1 . filePath ( ) ) ; } } } } //循环读取文件路径,后期可以考虑换成多线程-线程池来做. QFileInfoList MainWindow :: GetAllFileList ( QString path ) { QDir dir ( path ) ; QFileInfoList file_list = dir . entryInfoList ( QDir :: Files | QDir :: Hidden | QDir :: NoSymLinks ) ; QFileInfoList folder_list = dir . entryInfoList ( QDir :: Dirs | QDir :: NoDotAndDotDot ) ; for ( int i = 0 ; i != folder_list . size ( ) ; i ++ ) { QString name = folder_list . at ( i ) . absoluteFilePath ( ) ; QFileInfoList child_file_list = GetAllFileList ( name ) ; file_list . append ( child_file_list ) ; } return file_list ; }
拖放操作包括两个截然不同的动作:拖动、放下。Qt的窗口部件可以作为拖动点,也可以作为放下点,或者两者都是。
上面的MainWindow类实现了QWidget的dragEnterEvent() 和 dropEvent()函数。
当用户把一个对象拖动到窗口部件上时,就会调用dragEnterEvent()函数。如果对这个事件调用acceptProposedAction(),就表明用户可以在这个窗口部件上拖放对象。当然,默认情况下,窗口是不接受拖动的。Qt会自动改变光标来向用户说明这个窗口部件是不是有效的放下点。
当用户在窗口部件上放下一个对象时,就会调用DropEvent()。我们调用函数QMineData::urls()来获得QUrl列表。
QWidget也提供dragMoveEvent()和dragLeaveEvent()两个函数,不过在绝大多数应用程序中不需要实现他们。
