E-mail:zzssdd2@foxmail.com
一、前言开发环境:Qt5.12.10 + MinGW
功能
文件的发送
数据的保存
知识点
QFile类的使用
QTimer类的使用
文本的转码与编码识别
QPushButton、QProgressBar控件的使用
二、功能实现本章功能主要包含两个方面,一是通过串口发送选定的文本文件,二是将接收的数据保存为本地文本文件。最后还有对《QT串口助手(三):数据接收》章节内容进行一个补充扩展。
2.1、文件打开当选择文件按钮点击后,触发点击信号对应的槽函数,在槽函数中进行文件的打开与读取:
/*选择并打开文件*/ QString curPath = QDir::currentPath(); //系统当前目录 QString dlgTitle = "打开文件"; //对话框标题 QString filter = "文本文件(*.txt);;二进制文件(*.bin *.dat);;所有文件(*.*)"; //文件过滤器 QString filepath = QFileDialog::getOpenFileName(this,dlgTitle,curPath,filter); QFileInfo fileinfo(filepath); if (filepath.isEmpty()) { QMessageBox::warning(this,"警告","文件为空"); return; } //文件路径显示到发送框 ui->Send_TextEdit->clear(); ui->Send_TextEdit->appendPlainText(filepath); QFile file(filepath); if (!file.exists()) { QMessageBox::warning(this,"警告","文件不存在"); return; } if (!file.open(QIODevice::ReadOnly)) { QMessageBox::warning(this,"警告","文件打开失败"); return; } 2.2、编码判断因为应用程序默认使用的编码为UTF-8,如果打开GBK格式编码的文件就会乱码,所以需要判断文件的编码,如果不是UTF-8则需要对文件进行编码转换。
/* 设置应用程序的编码解码器 */ QTextCodec *codec = QTextCodec::codecForName("UTF-8"); QTextCodec::setCodecForLocale(codec);
[static] QTextCodec *QTextCodec::codecForName(const char *name)
Searches all installed QTextCodec objects and returns the one which best matches name; the match is case-insensitive. Returns 0 if no codec matching the name name could be found.
[static] void QTextCodec::setCodecForLocale(QTextCodec **c*)
Set the codec to c; this will be returned by codecForLocale(). If c is a null pointer, the codec is reset to the default.
This might be needed for some applications that want to use their own mechanism for setting the locale.
Warning: This function is not reentrant.
/* 判断编码 */ QTextCodec::ConverterState state; QTextCodec *codec = QTextCodec::codecForName("UTF-8"); FileText = codec->toUnicode(data.constData(),data.size(),&state); //若有无效字符则是GBK编码 if (state.invalidChars > 0) { //转码后返回 FileText = QTextCodec::codecForName("GBK")->toUnicode(data); } else { FileText = data; }对文件进行上述的处理后,如果是GBK编码则也能够正确的读取了。
QString QTextCodec::toUnicode(const char *input, int size, QTextCodec::ConverterState *state = nullptr) const
Converts the first size characters from the input from the encoding of this codec to Unicode, and returns the result in a QString.
The state of the convertor used is updated.
QString QTextCodec::toUnicode(const QByteArray &a) const
Converts a from the encoding of this codec to Unicode, and returns the result in a QString.
2.3、文件读取文件打开后,需要对文件类型进行判断,然后进行文件数据的读取:
/*判断文件类型*/ int type = 0; QMimeDatabase db; QMimeType mime = db.mimeTypeForFile(filepath); if (mime.name().startsWith("text/")) { type = 1; //文本文件 } else if (mime.name().startsWith("application/")) { type = 2; //二进制文件 }QMimeType QMimeDatabase::mimeTypeForFile(const QString&fileName, QMimeDatabase::MatchMode mode = MatchDefault) const
Returns a MIME type for the file named fileName using mode.
This is an overloaded function.
QMimeType 类描述文件或数据的类型,由 MIME 类型字符串表示,获取到文件类型后接下来就知道应该使用什么方法读取文件内容了。常见文件类型如下:
描述(startsWith) 类型 示例text 普通文本 text/plain, text/html, text/css, text/javascript
image 图像文件(包含动态gif) image/gif, image/png, image/jpeg, image/bmp, image/webp
audio 音频文件 audio/wav, audio/mpeg, audio/midi, audio/webm, audio/ogg
video 视频文件 video/mp4, video/x-flv, video/webm, video/ogg
application 二进制数据 application/xml, application/pdf
/*读取文件*/ switch(type) { case 1: { //QIODevice读取普通文本 QByteArray data = file.readAll(); file.close(); if (data.isEmpty()) { QMessageBox::information(this, "提示", "文件内容空"); return; } /* 判断编码 */ } break; case 2: { int filelen = fileinfo.size(); QVector<char> cBuf(filelen);//储存读出数据 //使用QDataStream读取二进制文件 QDataStream datain(&file); datain.readRawData(&cBuf[0],filelen); file.close(); //char数组转QString FileText = QString::fromLocal8Bit(&cBuf[0],filelen); } break; }
QByteArray QIODevice::readAll()
Reads all remaining data from the device, and returns it as a byte array.
This function has no way of reporting errors; returning an empty QByteArray can mean either that no data was currently available for reading, or that an error occurred.
int QDataStream::readRawData(char **s*, int len)
Reads at most len bytes from the stream into s and returns the number of bytes read. If an error occurs, this function returns -1.
The buffer s must be preallocated. The data is not decoded.