【问题标题】:Edit .txt file in QT在 QT 中编辑 .txt 文件
【发布时间】:2020-05-08 17:42:26
【问题描述】:

我有一个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 文件中访问这些值并进行更改吗?

附言

在上述配置文件中,cmets 用反引号 `` 括起来并替换为空格字符。单个反引号 ` 开始一个持续到行尾的注释。

编辑

从cmets,我尝试将问题分解为三个部分:

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();
    }

在这里我做了记忆的改变。

  1. 将新值写回文件(内容不变)。

这是我难以实现的。如何将这些修改后的行写回原始文件?

【问题讨论】:

  • 显示你尝试过的东西,即使它不起作用,清楚地指出你卡在哪里,因为 SO 不是 SW 写作服务
  • 您的文本文件中有一些可能不属于那里的单引号。如果您选择代码然后按编辑窗口顶部栏上的“代码示例”按钮,代码格式化会更容易
  • @foreknownas_463035818 您好,在我的配置文件中,cmets 用反引号 ` ` 括起来并替换为空格字符。单个反引号 ` 开始一个持续到行尾的注释。
  • 好的,那么请将此信息添加到问题中,因为它并不明显。糟糕的格式看起来很相似;)
  • 这个问题由三个部分组成:1)读取文件并提取O行的内容; 2)用它来呈现一个带有滑块的屏幕; 3) 将新值写回文件(可能内容完整)。你分别尝试了什么?

标签: c++ qt qtgui


【解决方案1】:

最好将这三个步骤分开,所以在(未经测试的)代码中:

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;
}

【讨论】:

  • 非常感谢您的回答。您能否在此处提供有关如何设置model 的更多信息?那个模型是从哪里来的?你提到了getModelFromFile,我们如何实现它?
  • 你实现它就像你已经拥有的一样:逐行读取文件。当您看到带有O CH 的行时,将其用空格分隔,将相应列中的值推入向量中。
  • this-&gt;model = getModelFromFile("..."); 这个我还是不明白,这里的model 是一个List 模型?,你能给我一个简单的例子如何实现吗?
  • 在我的回答中添加了一个非常基本的实现。请注意,它要求所有通道值都是有序的,并且没有间隙。
  • 非常感谢您的进一步澄清。在这里,this-&gt;model 是什么model?,如何初始化model
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2013-03-28
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2021-10-23
相关资源
最近更新 更多