qt下实现文件的拖拽打开

引言

此文用于记录按下鼠标左键不放,拖动文件到程序中打开。该示例中只设置了可以拖动的文件类型为.h,.cpp,.txt这三种文件类型。

程序运行的效果:

qt下实现文件的拖拽打开_第1张图片

示例

下面是具体的实现。
项目的结构:
qt下实现文件的拖拽打开_第2张图片
具体的实现代码,如下:
main.cpp

#include "dialog.h"

#include 

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 

/********************************************
        ======功能描述:=======
        1.实现文件的拖拽打开。
********************************************/

QT_BEGIN_NAMESPACE
namespace Ui { class Dialog; }
QT_END_NAMESPACE

class Dialog : public QDialog
{
    Q_OBJECT

public:
    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 
#include 
#include 
#include 
#include 

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文件的结构
qt下实现文件的拖拽打开_第3张图片
以上便是文件拖拽打开的实现。
值得注意的是:
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);其次改类的子控件必须设置为不接受拖拽,这样当事件到来的时候,改类被重写的拖拽事件便会去处理。如果子控件没有设置不接受拖拽,那么拖拽事件会直接在子控件的拖拽事件中处理。

你可能感兴趣的:(Qt)