在QT中编辑.txt文件
Edit .txt file in QT
我有一个 txt
文件来配置串行设备的设置,如下所示:
`R ref, version, "config_ID", menu language, Power timeout (hours), Number of users
R R1 1 "Template for setting parameters" ENGLISH 1 1
`U ref, "user name", language, volume, number of activities
U U1 "Any user" ENGLISH 100% 1
`A ref, "activity name", max duration, max cycles, startingPW%, available/hidden
A A1 "Setup stim levels" 0min 0 0% AVAILABLE FALSE FALSE TRUE TRUE
B SA1 1 "Engine tests"
` These limits apply to all phases
` M ref stim, channel, max current, minPW, maxPW, freq, waveform, output name
M CH1 1 1 120mA 10us 450us 40Hz ASYM "Channel 1"
M CH2 1 2 120mA 10us 450us 40Hz ASYM "Channel 2"
P P0 "Test phase" 0ms NONE 2000ms STOP STOP STOP
` Delay RR rate PW
O CH1 0mA 0ms 0ms 600000ns 180us RATE
O CH2 0mA 0ms 0ms 600000ns 180us RATE
在我的程序中,我需要读取这个文件并更改一些值并保存。
例如,在正文的最后几行:
P P0 "Test phase" 0ms NONE 2000ms STOP STOP STOP
` Delay RR rate PW
O CH1 0mA 0ms 0ms 600000ns 180us RATE
O CH2 0mA 0ms 0ms 600000ns 180us RATE
我需要将那些 PW
值 (180us
) 更改为通过 QSlider
调整的值
ui->verticalSlider_ch1->value()
ui->verticalSlider_ch2->value()
你能告诉我如何从 txt 文件中访问这些值并进行更改吗?
p.s.
在上述配置文件中,注释用反引号``括起来并用space字符替换。单个反引号 ` 开始注释,该注释一直持续到行尾。
编辑
根据评论,我尝试将问题分解为三个部分:
1) 读取文件并提取 O 行的内容,2) 使用它来呈现带有滑块的屏幕
QString filename = "config_keygrip";
QString path = QCoreApplication::applicationDirPath()+"/"+filename+".txt";
QFile file(path);
if(!file.open(QIODevice::ReadOnly | QIODevice::Text))
{
QMessageBox::information(this, "Unable to open file for read", file.errorString());
return;
}
else
{
QTextStream in(&file);
while(!in.atEnd())
{
QString line = in.readLine();
QString trackName("O CH1");
int pos = line.indexOf(trackName);
if (pos >= 0)
{
QStringList list = line.split(' ', QString::SkipEmptyParts); // split line and get value
QString currVal = QString::number(ui->verticalSlider->value());
list[3] = currVal; // replace value at position 3 with slider value
}
}
file.close();
}
这里我在内存中做了改动。
- 正在将新值写回文件(内容完好无损)。
这是我难以实现的事情。如何将这些修改后的行写回原始文件?
最好将这三个步骤分开,因此在(未测试的)代码中:
struct Model { QVector<int> values; };
// I'm assuming you call this function when you start the program.
void MyWindow::load() {
this->model = getModelFromFile("...");
// set up UI according to model, this is just an example
ui->verticalSlider->value = this->model.values[0];
QObject::connect(ui->verticalSlider, &QSlider::valueChanged,
[=](int value) { this->model.values[0] = value; });
QObject::connect(ui->saveButton, &QPushButton::clicked, this, &MyWindow::saveModelToFile);
}
这允许您使用(当前为 1,但可能有很多)滑块来操作 Model
结构的值。
它假定有一个保存按钮,单击时调用以下方法。
此方法的要点是您打开原始文件以供读取,同时打开一个新文件以供写入,然后复制行(如果不是 O CH
行)或替换行中的值。最后用新写入的文件替换原来的文件。
void MyWindow::saveModelToFile() {
QString filename = "config_keygrip";
QString path = QCoreApplication::applicationDirPath()+"/"+filename+".txt";
QFile originalFile(path);
originalFile.open(QIODevice::ReadOnly | QIODevice::Text); // TODO: error handling
QFile newFile(path+".new");
newFile.open(QIODevice::WriteOnly | QIODevice::Text); // TODO: error handling
while (!originalFile.atEnd()) {
QByteArray line = originalFile.readLine();
if (line.contains("O CH")) {
QStringList list = QString::fromUtf8(line).split(' ', QString::SkipEmptyParts);
int channel = list[1].mid(2).toInt(); // list[1] is "CHx"
list[6] = QString("%1us").arg(this->model.values[channel - 1]); // actually replace the value
line = list.join(" ").toUtf8();
}
// copy the line to newFile
newFile.write(line);
}
// If we got this far, we can replace originalFile with newFile.
newFile.close();
originalFile.close();
QFile(path+".old").remove();
originalFile.rename(path+".old");
newFile.rename(path);
}
getModelFromFile
的基本实现,没有错误处理且未经测试:
Model getModelFromFile(QString path) {
Model ret;
QFile file(path);
file.open(QIODevice::ReadOnly | QIODevice::Text);
while (!file.atEnd()) {
QByteArray line = file.readLine();
if (line.contains("O CH")) {
QStringList list = QString::fromUtf8(line).split(' ', QString::SkipEmptyParts);
int value = list[6].remove("us").toInt();
ret.values.push_back(value);
}
}
return ret;
}
我有一个 txt
文件来配置串行设备的设置,如下所示:
`R ref, version, "config_ID", menu language, Power timeout (hours), Number of users
R R1 1 "Template for setting parameters" ENGLISH 1 1
`U ref, "user name", language, volume, number of activities
U U1 "Any user" ENGLISH 100% 1
`A ref, "activity name", max duration, max cycles, startingPW%, available/hidden
A A1 "Setup stim levels" 0min 0 0% AVAILABLE FALSE FALSE TRUE TRUE
B SA1 1 "Engine tests"
` These limits apply to all phases
` M ref stim, channel, max current, minPW, maxPW, freq, waveform, output name
M CH1 1 1 120mA 10us 450us 40Hz ASYM "Channel 1"
M CH2 1 2 120mA 10us 450us 40Hz ASYM "Channel 2"
P P0 "Test phase" 0ms NONE 2000ms STOP STOP STOP
` Delay RR rate PW
O CH1 0mA 0ms 0ms 600000ns 180us RATE
O CH2 0mA 0ms 0ms 600000ns 180us RATE
在我的程序中,我需要读取这个文件并更改一些值并保存。
例如,在正文的最后几行:
P P0 "Test phase" 0ms NONE 2000ms STOP STOP STOP
` Delay RR rate PW
O CH1 0mA 0ms 0ms 600000ns 180us RATE
O CH2 0mA 0ms 0ms 600000ns 180us RATE
我需要将那些 PW
值 (180us
) 更改为通过 QSlider
ui->verticalSlider_ch1->value()
ui->verticalSlider_ch2->value()
你能告诉我如何从 txt 文件中访问这些值并进行更改吗?
p.s.
在上述配置文件中,注释用反引号``括起来并用space字符替换。单个反引号 ` 开始注释,该注释一直持续到行尾。
编辑
根据评论,我尝试将问题分解为三个部分:
1) 读取文件并提取 O 行的内容,2) 使用它来呈现带有滑块的屏幕
QString filename = "config_keygrip";
QString path = QCoreApplication::applicationDirPath()+"/"+filename+".txt";
QFile file(path);
if(!file.open(QIODevice::ReadOnly | QIODevice::Text))
{
QMessageBox::information(this, "Unable to open file for read", file.errorString());
return;
}
else
{
QTextStream in(&file);
while(!in.atEnd())
{
QString line = in.readLine();
QString trackName("O CH1");
int pos = line.indexOf(trackName);
if (pos >= 0)
{
QStringList list = line.split(' ', QString::SkipEmptyParts); // split line and get value
QString currVal = QString::number(ui->verticalSlider->value());
list[3] = currVal; // replace value at position 3 with slider value
}
}
file.close();
}
这里我在内存中做了改动。
- 正在将新值写回文件(内容完好无损)。
这是我难以实现的事情。如何将这些修改后的行写回原始文件?
最好将这三个步骤分开,因此在(未测试的)代码中:
struct Model { QVector<int> values; };
// I'm assuming you call this function when you start the program.
void MyWindow::load() {
this->model = getModelFromFile("...");
// set up UI according to model, this is just an example
ui->verticalSlider->value = this->model.values[0];
QObject::connect(ui->verticalSlider, &QSlider::valueChanged,
[=](int value) { this->model.values[0] = value; });
QObject::connect(ui->saveButton, &QPushButton::clicked, this, &MyWindow::saveModelToFile);
}
这允许您使用(当前为 1,但可能有很多)滑块来操作 Model
结构的值。
它假定有一个保存按钮,单击时调用以下方法。
此方法的要点是您打开原始文件以供读取,同时打开一个新文件以供写入,然后复制行(如果不是 O CH
行)或替换行中的值。最后用新写入的文件替换原来的文件。
void MyWindow::saveModelToFile() {
QString filename = "config_keygrip";
QString path = QCoreApplication::applicationDirPath()+"/"+filename+".txt";
QFile originalFile(path);
originalFile.open(QIODevice::ReadOnly | QIODevice::Text); // TODO: error handling
QFile newFile(path+".new");
newFile.open(QIODevice::WriteOnly | QIODevice::Text); // TODO: error handling
while (!originalFile.atEnd()) {
QByteArray line = originalFile.readLine();
if (line.contains("O CH")) {
QStringList list = QString::fromUtf8(line).split(' ', QString::SkipEmptyParts);
int channel = list[1].mid(2).toInt(); // list[1] is "CHx"
list[6] = QString("%1us").arg(this->model.values[channel - 1]); // actually replace the value
line = list.join(" ").toUtf8();
}
// copy the line to newFile
newFile.write(line);
}
// If we got this far, we can replace originalFile with newFile.
newFile.close();
originalFile.close();
QFile(path+".old").remove();
originalFile.rename(path+".old");
newFile.rename(path);
}
getModelFromFile
的基本实现,没有错误处理且未经测试:
Model getModelFromFile(QString path) {
Model ret;
QFile file(path);
file.open(QIODevice::ReadOnly | QIODevice::Text);
while (!file.atEnd()) {
QByteArray line = file.readLine();
if (line.contains("O CH")) {
QStringList list = QString::fromUtf8(line).split(' ', QString::SkipEmptyParts);
int value = list[6].remove("us").toInt();
ret.values.push_back(value);
}
}
return ret;
}