Qt实现数据文本保存TXT文件

本文介绍如何利用Qt的QFile和QTextStream类将数据保存为TXT文件。通过简单的步骤,包括设置头文件、定义槽函数以及信号与槽的连接,实现了数据的保存功能。

本博客主要用于实现数据文本的保存成TXT文件

先看结果图test.txt被保存在C盘,如下图所示

创建步骤还是那么传统的几个过程

1.evgui.h(我自己的头文件.h文件就是了)

记得添加头文件

 
#include <QtCore/QTextStream> #include <QtCore/QFile> #include <QtCore/QIODevice> 

 

 

 

 

 

后面就是声明槽函数部分了

 

private slots:
    void saveTxt();
 

2.evgui.cpp部分创建具体的槽函数

 

 

 
///////保存数据文本 void EVgui::saveTxt() { QString sFilePath="C:\\test.txt"; QFile file(sFilePath); if(!file.open(QIODevice::WriteOnly|QIODevice::Text)) { QMessageBox::critical(NULL,"提示","无法创建文件"); return; } out<<a<<endl;//将a存进test.txt文件夹里面 out.flush(); file.close(); }

 

 

 

 

 

3.信号与槽函数连接机制

 

 

//在此处槽函数调用的是QTimer类的对象实例化clk,在这里clk.start()可自行看帮助文档,clk.start(msec单触发定时器).因为这里都是视频流形式,需要摄像头,可以改为pushbutton的出发机制

 
EVgui::EVgui(QWidget *parent) : QMainWindow(parent), ui(new Ui::EVgui) { ui->setupUi(this); clk.start(10); QObject::connect(&clk, SIGNAL(timeout()), this, SLOT(saveTxt())); }

 

由于时间久远,对上面的内容只作为自己的记录,后面在应用qt时都不在采用vs+qt插件形式,全面采用了qt create形式,后者会比较的简单。这里奉上自己的一篇文章,很快的入门:一个项目带你快速入门 Qt Creator

 

 

 

 

 

 

<think>我们正在使用C++和Qt来将串口数据追加保存TXT文件中。根据引用[2]的内容,我们知道设计思路包括串口数据的收发和文件操作。因此,我们需要: 1. 使用Qt串口类(QSerialPort)来接收串口数据。 2. 将接收到的数据追加到TXT文件中。 步骤: 1. 创建Qt项目,并在.pro文件中添加串口模块:`QT += serialport` 2. 在代码中包含必要的头文件: ```cpp #include <QSerialPort> #include <QSerialPortInfo> #include <QFile> #include <QTextStream> #include <QDebug> ``` 3. 初始化串口,设置参数(波特率、数据位、停止位、校验位等)。 4. 打开串口并连接其readyRead信号到槽函数,以便在数据到来时读取。 5. 在槽函数中读取串口数据,然后将数据追加到TXT文件中。 注意:追加写入文件时,我们使用QFile的追加模式(QIODevice::Append)。 示例代码: 假设我们有一个类(例如Widget),在其中处理串口文件操作。 在widget.h中: ```cpp #ifndef WIDGET_H #define WIDGET_H #include <QWidget> #include <QSerialPort> class Widget : public QWidget { Q_OBJECT public: explicit Widget(QWidget *parent = nullptr); ~Widget(); private slots: void readSerialData(); // 读取串口数据的槽函数 private: QSerialPort *serial; // 串口对象 QFile file; // 文件对象 }; #endif // WIDGET_H ``` 在widget.cpp中: ```cpp #include "widget.h" #include <QCoreApplication> #include <QFile> #include <QTextStream> #include <QDebug> Widget::Widget(QWidget *parent) : QWidget(parent) { // 初始化串口 serial = new QSerialPort(this); serial->setPortName("COM1"); // 设置串口号,根据实际情况修改 serial->setBaudRate(QSerialPort::Baud9600); serial->setDataBits(QSerialPort::Data8); serial->setParity(QSerialPort::NoParity); serial->setStopBits(QSerialPort::OneStop); serial->setFlowControl(QSerialPort::NoFlowControl); // 打开串口 if (serial->open(QIODevice::ReadOnly)) { qDebug() << "Serial port opened"; // 连接信号槽,当有数据可读时,调用readSerialData connect(serial, &QSerialPort::readyRead, this, &Widget::readSerialData); } else { qDebug() << "Failed to open serial port:" << serial->errorString(); } // 设置文件路径并打开文件(追加模式) file.setFileName("serial_data.txt"); if (!file.open(QIODevice::Append | QIODevice::Text)) { qDebug() << "Failed to open file:" << file.errorString(); } } Widget::~Widget() { if (file.isOpen()) { file.close(); } if (serial->isOpen()) { serial->close(); } delete serial; } void Widget::readSerialData() { // 读取所有数据 QByteArray data = serial->readAll(); // 将数据写入文件(追加) if (file.isOpen()) { QTextStream out(&file); out << data; // 注意:我们不需要每次写入后都flush,因为QTextStream会缓冲,但为了确保数据及时写入,可以调用flush // out.flush(); // 如果需要立即写入,取消注释 } else { qDebug() << "File is not open!"; } // 同时输出到调试窗口 qDebug() << "Received data:" << data; } ``` 注意: 1. 串口号(如COM1)需要根据实际情况修改。 2. 文件路径为当前目录下的"serial_data.txt",如果文件不存在,则会创建;如果存在,则在末尾追加。 3. 写入文件时,我们使用了QTextStream,它会将QByteArray转换为QString(使用默认的UTF-8编码)。如果串口数据是二进制数据,可能需要使用QDataStream或者直接使用file.write(data)来写入原始字节。但这里我们按照文本追加的方式。 如果串口数据文本数据(例如ASCII或UTF-8),那么上述方法可行。如果是二进制数据,则应该使用二进制方式写入,并注意追加写入时不会破坏原有二进制数据。 修改为二进制追加写入: 在打开文件时使用`QIODevice::Append`(不加Text标志),然后使用`file.write(data)`。 修改文件打开方式: ```cpp if (!file.open(QIODevice::Append)) { // 二进制追加,没有Text标志 qDebug() << "Failed to open file:" << file.errorString(); } ``` 在readSerialData槽函数中写入: ```cpp if (file.isOpen()) { file.write(data); // 如果需要立即写入磁盘,可以调用flush // file.flush(); } ``` 根据引用[2]中的文件保存部分,我们还需要注意重复文件保存的问题(避免覆盖已有文件)。但用户要求是追加保存到同一个TXT文件,因此我们不需要每次创建新文件,而是追加到同一个文件。 但是,如果程序多次运行,每次都会重新打开文件(追加模式),所以数据会接着之前的文件末尾继续写入。如果用户希望每次运行都创建一个新的文件,那么需要生成不同的文件名(例如包含时间戳)。不过根据问题描述,只需要追加保存,所以上述代码满足要求。 另外,注意在程序结束时关闭文件,我们在析构函数中已经做了。 以上代码提供了一个基本的框架,实际使用时可能需要根据具体情况调整(例如错误处理、串口参数动态设置等)。 相关问题: 1. 如何动态选择串口号和设置串口参数? 2. 如果串口数据量很大,频繁写入文件会不会影响性能?如何优化? 3. 如何将接收到的数据同时显示在界面上并保存文件?</think>### 使用 C++ 和 Qt 实现串口数据追加保存TXT 文件 #### 核心步骤 1. **初始化串口** ```cpp #include <QSerialPort> #include <QFile> // 创建串口对象 QSerialPort *serial = new QSerialPort(this); serial->setPortName("COM3"); // 设置串口号 serial->setBaudRate(QSerialPort::Baud9600); // 设置波特率 serial->setDataBits(QSerialPort::Data8); // 数据位 serial->setParity(QSerialPort::NoParity); // 校验位 serial->setStopBits(QSerialPort::OneStop); // 停止位 if (serial->open(QIODevice::ReadOnly)) { qDebug() << "串口打开成功"; } else { qDebug() << "串口打开失败:" << serial->errorString(); } ``` 2. **创建文件对象(追加模式)** ```cpp QFile file("serial_data.txt"); if (!file.open(QIODevice::Append | QIODevice::Text)) { qDebug() << "文件打开失败:" << file.errorString(); return; } ``` 3. **连接信号槽读取数据** ```cpp // 当串口数据可读时触发 connect(serial, &QSerialPort::readyRead, [&]() { QByteArray data = serial->readAll(); // 读取所有数据 // 写入文件(追加模式) QTextStream out(&file); out << data << "\n"; // 换行分隔每条数据 // 可选:立即刷新缓冲区 out.flush(); qDebug() << "收到数据:" << data; }); ``` 4. **关闭资源(析构函数中)** ```cpp file.close(); // 关闭文件 serial->close(); // 关闭串口 ``` #### 完整示例代码 ```cpp #include <QCoreApplication> #include <QSerialPort> #include <QFile> #include <QTextStream> int main(int argc, char *argv[]) { QCoreApplication a(argc, argv); // 1. 初始化串口 QSerialPort serial; serial.setPortName("COM3"); serial.setBaudRate(QSerialPort::Baud9600); if (!serial.open(QIODevice::ReadOnly)) { qDebug() << "串口打开失败:" << serial.errorString(); return -1; } // 2. 打开文件(追加模式) QFile file("serial_data.txt"); if (!file.open(QIODevice::Append | QIODevice::Text)) { qDebug() << "文件打开失败:" << file.errorString(); return -1; } QTextStream out(&file); // 3. 连接数据接收槽 QObject::connect(&serial, &QSerialPort::readyRead, [&]() { QByteArray data = serial.readAll(); out << data << "\n"; // 追加数据并换行 out.flush(); // 确保数据写入磁盘 qDebug() << "已保存:" << data; }); return a.exec(); } ``` #### 关键注意事项 1. **文件追加模式** 使用 `QIODevice::Append` 标志确保新数据添加到文件末尾: ```cpp file.open(QIODevice::Append | QIODevice::Text); ``` 2. **数据格式处理** - 文本数据:直接使用 `QTextStream` 写入 - 二进制数据:改用 `file.write(data)` 写入原始字节 3. **错误处理** 始终检查操作结果: ```cpp if (!serial.open(...)) { /* 处理错误 */ } if (!file.open(...)) { /* 处理错误 */ } ``` 4. **性能优化** 大数据量时减少写磁盘次数: ```cpp // 每10次写入刷新一次 static int count = 0; if (++count % 10 == 0) out.flush(); ``` 5. **文件路径问题** 建议使用绝对路径避免路径歧义: ```cpp QFile file("C:/Data/serial_log.txt"); ``` #### 常见问题解决 - **中文乱码**:在文件开头添加BOM标记 ```cpp out.setGenerateByteOrderMark(true); // 生成UTF-8 BOM ``` - **数据堆积**:使用缓冲区定期写入 - **重复文件**:实现引用[1]中的防覆盖逻辑 ```cpp QString path = "data.txt"; int i = 0; while (QFile::exists(path)) { path = QString("data_%1.txt").arg(++i); } ```
评论 4
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

钱多多先森

你的鼓励,是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值