Редактировать .txt файл в QT - PullRequest
0 голосов
/ 22 января 2020

У меня есть файл 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 и изменить его?

ps

В вышеупомянутом файле конфигурации , комментарии заключаются в символы `` и заменяются пробелами. Одиночный обратный удар `запускает комментарий, который продолжается до конца строки.

РЕДАКТИРОВАТЬ

Из комментариев я попытался разбить проблему на три части:

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 Ответ

3 голосов
/ 24 января 2020

Было бы лучше, если бы вы держали эти три шага отдельно, поэтому в (непроверенном) коде:

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

Это позволяет вам манипулировать значениями структуры Model с (в настоящее время 1, но возможно много) слайдер (ы). Предполагается, что есть кнопка сохранения, которая при нажатии вызывает следующий метод. Суть этого метода в том, что вы открываете исходный файл для чтения вместе с файлом fre sh для записи и либо копируете строки (если не строка 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);
}

Базовая c реализация 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;
}
...