引言
此文用于记录按下鼠标左键不放,拖动文件到程序中打开。该示例中只设置了可以拖动的文件类型为.h,.cpp,.txt这三种文件类型。
程序运行的效果:
示例
下面是具体的实现。
项目的结构:
具体的实现代码,如下:
main.cpp
#include "dialog.h"#include <QApplication>int main(int argc, char *argv[])
{QApplication a(argc, argv);Dialog w;w.show();return a.exec();
}
dialog.h
#ifndef DIALOG_H
#define DIALOG_H#include <QDialog>/********************************************======功能描述:=======1.实现文件的拖拽打开。
********************************************/QT_BEGIN_NAMESPACE
namespace Ui { class Dialog; }
QT_END_NAMESPACEclass Dialog : public QDialog
{Q_OBJECTpublic:Dialog(QWidget *parent = nullptr);~Dialog();
protected:void dragEnterEvent(QDragEnterEvent *event);//拖拽进入void dropEvent(QDropEvent *event);//释放拖拽的文件QString GetCorrectUnicode(const QByteArray &ba);//返回ba的UTF-8编码的QString字符串
private:Ui::Dialog *ui;
};
#endif // DIALOG_H
dialog.cpp
#include "dialog.h"
#include "ui_dialog.h"
#include <QDragEnterEvent>
#include <QMimeData>
#include <QFile>
#include <QTextCodec>
#include <QDebug>Dialog::Dialog(QWidget *parent): QDialog(parent), ui(new Ui::Dialog)
{ui->setupUi(this);setAcceptDrops(true);ui->textEdit->setAcceptDrops(false);//设置不接收拖拽事件,否则会进入该子控件的拖拽事件中
}Dialog::~Dialog()
{delete ui;
}void Dialog::dragEnterEvent(QDragEnterEvent *event)
{if (event->mimeData()->hasUrls()) {event->acceptProposedAction();}else {event->ignore();}
}void Dialog::dropEvent(QDropEvent *event)
{if (event->mimeData()->hasUrls() && (event->mimeData()->urls()[0].fileName().right(3).compare("cpp") == 0|| event->mimeData()->urls()[0].fileName().right(3).compare("txt") == 0|| event->mimeData()->urls()[0].fileName().right(1).compare("h") == 0)) {const QList<QUrl> urls = event->mimeData()->urls();QString filePath = urls.at(0).toLocalFile();QFile file(filePath);if (file.open(QIODevice::ReadOnly)) {QByteArray byteArray = file.readAll();QString strContent = GetCorrectUnicode(byteArray);//返回utf-8编码的字符串QString
// QString strContent = QString::fromLocal8Bit(byteArray).toUtf8();//当文件的编码格式为GB2312编码,采用这种方式不乱码
// QString strContent = byteArray;//当文件本身的编码格式为utf-8时,采用这种方式不乱码ui->textEdit->setText(strContent);}else {qDebug()<<QStringLiteral("文件")<<filePath<<QStringLiteral("打不开");}}
}QString Dialog::GetCorrectUnicode(const QByteArray &ba)
{QTextCodec::ConverterState state;QTextCodec *codec = QTextCodec::codecForName("UTF-8");codec->toUnicode( ba.constData(), ba.size(), &state);if (state.invalidChars > 0){return QTextCodec::codecForName( "GBK" )->toUnicode(ba);}else{return ba;}
}
ui文件的结构
以上便是文件拖拽打开的实现。
值得注意的是:
1.文件txt,.cpp,.h可能会以不同的编码格式保存,这里函数GetCorrectUnicode(const QByteArray &ba)可以将字符串转换为Utf-8编码的QString字符串。所以无论是那种格式应该都可以正常的拖拽加载到显示文本中。
2.对于单一的编码格式保存的文件,可以单一处理。当文件的编码格式为utf-8时,可以直接将从文件中读取的内容设置到显示文本。如:
QByteArray byteArray = file.readAll();QString strContent = byteArray;//当文件本身的编码格式为utf-8时,采用这种方式含中文不乱码。
当文件保存的编码格式为gb2312时,这时可以这样处理:
QByteArray byteArray = file.readAll();
QString strContent = QString::fromLocal8Bit(byteArray).toUtf8();//当文件的编码格式为GB2312编码,采用这种方式不乱码
可以看出还是采用将编码格式统一转换为utf-8比较方便,这样就不用区分文件保存时的编码格式了。
3.对于文件拖拽,首先改类必须能够接收拖拽,也就是必须在构造函数中设置setAcceptDrops(true);其次改类的子控件必须设置为不接受拖拽,这样当事件到来的时候,改类被重写的拖拽事件便会去处理。如果子控件没有设置不接受拖拽,那么拖拽事件会直接在子控件的拖拽事件中处理。