U
Ulkiorra199214. März 2018 10:21

QSettings

Добрый день, есть задача сохранить значения из CheckBox, ComboBox, RadioButton, slider, в файл для того что бы можно было при повторном запуске приложения загрузить предыдущие настройки и продолжить работу, реализовал это следующим образом:

mainwindow.h

#pragma once

#include <QMainWindow>
#include <QSettings>

namespace Ui {
class MainWindow;
}

class MainWindow : public QMainWindow
{
    Q_OBJECT

public:
    explicit MainWindow(QWidget *parent = 0);
    ~MainWindow();

private slots:
    void on_Save_triggered();
    void on_Load_triggered();

private:
    Ui::MainWindow *ui;
};
mainwindow.cpp
#include "mainwindow.h"
#include "ui_mainwindow.h"

#include <QDebug>
#include <QToolTip>
#include <QDateTime>
#include <QFileDialog>
#include <QCoreApplication>
#include <QSlider>

MainWindow::MainWindow(QWidget *parent) :
    QMainWindow(parent),
    ui(new Ui::MainWindow)
{
    ui->setupUi(this);
}

MainWindow::~MainWindow()
{
    delete ui;
}

void MainWindow::on_Save_triggered()
{
    QDate date = QDate::currentDate();  // получаем текущую дату
    QTime time = QTime::currentTime();  // получаем текущее время

/* записываем имя файла с настройками, qApp->applicationDirPath() - директория где лежит exe файл проекта
 * QString("/%0_%1.ini") - формируем имя файла в формате .ini специальный формат для хранения настроек
 * date.toString("dd-MM-yyyy") - дата - в формате день недели_месяц_год
 * time.toString("hh-mm") - время в формате часы_минуты_секунды
 */
    QString fileName = qApp->applicationDirPath().append(
                QString("/%0_%1.ini").arg(date.toString("dd-MM-yyyy")).arg(time.toString("hh-mm")));

    QSettings settings(fileName, QSettings::IniFormat);

    settings.beginGroup("checkBox");   
    settings.setValue("checkBox_1", ui->checkBox->isChecked()); 
    settings.setValue("checkBox_2", ui->checkBox_2->isChecked());
    settings.setValue("checkBox_3", ui->checkBox_3->isChecked());
    settings.setValue("checkBox_4", ui->checkBox_4->isChecked());
    settings.setValue("checkBox_5", ui->checkBox_5->isChecked());
    settings.setValue("checkBox_6", ui->checkBox_6->isChecked());
    settings.endGroup();               

    settings.beginGroup("slider");
    settings.setValue("horizontalSlider", ui->horizontalSlider->value());
    settings.endGroup();
}

void MainWindow::on_Load_triggered()
{
// создаем переменную fileName куда запишется путь до выбранного нами файла
    QString fileName = QFileDialog::getOpenFileName(0, "Open", "/", "");
    QSettings settings(fileName, QSettings::IniFormat);

    settings.beginGroup("checkBox");
/* присваваем checkBox значение считанное из файла для этого указываем "ключ" т.е. имя "checkBox_1"
 * далее после запятой пишем значение по умолчанию, на случай если не будет считано значение из файла "false"
 * далее указываем тип значения .toBool() т.е. получаем значения true или false.
 */
    ui->checkBox->setChecked(settings.value("checkBox_1", false).toBool());
    ui->checkBox_2->setChecked(settings.value("checkBox_2", false).toBool());
    ui->checkBox_3->setChecked(settings.value("checkBox_3", false).toBool());
    ui->checkBox_4->setChecked(settings.value("checkBox_4", false).toBool());
    ui->checkBox_5->setChecked(settings.value("checkBox_5", false).toBool());
    ui->checkBox_6->setChecked(settings.value("checkBox_6", false).toBool());
    settings.endGroup();

// вот пример со слайдером  тип значения для него .toInt()
    settings.beginGroup("slider");
    ui->horizontalSlider->setValue(settings.value("horizontalSlider", 0).toInt());
    settings.endGroup();
}

я все сохраняю через QSettings, но на форме будет до 100 элементов, и интересно, возможно как то оптимизировать код, что бы не было 100 строчек для записи и 100 строчек для чтения из файла

Рекомендуємо хостинг TIMEWEB
Рекомендуємо хостинг TIMEWEB
Stabiles Hosting des sozialen Netzwerks EVILEG. Wir empfehlen VDS-Hosting für Django-Projekte.

Magst du es? In sozialen Netzwerken teilen!

4
Evgenii Legotckoi
  • 16. März 2018 06:39

Добрый день!

Несколько упростить это можно.
Например, если у вас будет специальная структура, которая будет хранить информацию о чекбоксах (указатели на них) и информацию об этой настройке в QSettings, тогда можно будет уменьшить код почти вдвое.

То есть имеем вот такую структуру
struct CheckBoxInfo 
{
    QString settingsName;
    QCheckBox* checkBox;
}
В заголовочном файле MainWindow объявляете вектор с такой структурой.
QVector<CheckBoxInfo> m_checkBoxes;
Далее в конструкторе класса MainWindow до чтения или записи настроек нужно заполнить этот вектор данными о чекбоксах.
m_checkBoxes = {
    {"checkBox_1", ui->checkBox},
    {"checkBox_2", ui->checkBox_2},
    {"checkBox_3", ui->checkBox_3},
    {"checkBox_4", ui->checkBox_4}
}
После чего запись и чтение настроек можно производить в цикле.
QSettings settings(fileName, QSettings::IniFormat);

settings.beginGroup("checkBox");   

for (auto& checkBoxInfo : m_checkBoxes)
{
    settings.setValue(checkBoxInfo.settingsName, checkBoxInfo.checkBox->isChecked());
}

settings.endGroup();
Аналогично для чтения
    U
    • 17. März 2018 04:57
    m_checkBoxes = {
        {"checkBox_1", ui->checkBox},
        {"checkBox_2", ui->checkBox_2},
        {"checkBox_3", ui->checkBox_3},
        {"checkBox_4", ui->checkBox_4}
    }
    ругается компилятор на это, "пишет синтаксическая ошибка {"  компилятор студиа 2010, заполнить вектор по другому не получается
      Evgenii Legotckoi
      • 17. März 2018 17:12

      ммм... у Вас 11-й стандарт C++ не поддерживается.  Это конструкция использует initializer_list.

      Тогда, раз уж всё так запущено, то используйте вектор из стандартной библиотеки, то есть std::vector.
      И для структуры создайте конструктор, в который можно будет передавать значения данных аргументов.

      Это будет выглядеть примерно так.
      #include <vector>
      
      struct Info
      {
          Info(int f, int s) : first(f), second(s) {}
      
          int first;
          int second;
      };
      
      std::vector<Info> vec;
      
      int main(int argc, char *argv[])
      {
          vec.push_back(Info(1, 2));
      
          return 0;
      }
        U
        • 18. März 2018 00:08

        спасибо)


          Kommentare

          Nur autorisierte Benutzer können Kommentare posten.
          Bitte Anmelden oder Registrieren
          Letzte Kommentare
          A
          ALO1ZE19. Oktober 2024 15:19
          Fb3-Dateileser auf Qt Creator Подскажите как это запустить? Я не шарю в программировании и кодинге. Скачал и установаил Qt, но куча ошибок выдается и не запустить. А очень надо fb3 переконвертировать в html
          ИМ
          Игорь Максимов5. Oktober 2024 14:51
          Django – Lektion 064. So schreiben Sie eine Python-Markdown-Erweiterung Приветствую Евгений! У меня вопрос. Можно ли вставлять свои классы в разметку редактора markdown? Допустим имея стандартную разметку: <ul> <li></li> <li></l…
          d
          dblas55. Juli 2024 18:02
          QML - Lektion 016. SQLite-Datenbank und das Arbeiten damit in QML Qt Здравствуйте, возникает такая проблема (я новичок): ApplicationWindow неизвестный элемент. (М300) для TextField и Button аналогично. Могу предположить, что из-за более новой верси…
          k
          kmssr9. Februar 2024 02:43
          Qt Linux - Lektion 001. Autorun Qt-Anwendung unter Linux как сделать автозапуск для флэтпака, который не даёт создавать файлы в ~/.config - вот это вопрос ))
          Qt WinAPI - Lektion 007. Arbeiten mit ICMP-Ping in Qt Без строки #include <QRegularExpressionValidator> в заголовочном файле не работает валидатор.
          Jetzt im Forum diskutieren
          J
          JacobFib17. Oktober 2024 10:27
          добавить qlineseries в функции Пользователь может получить любые разъяснения по интересующим вопросам, касающимся обработки его персональных данных, обратившись к Оператору с помощью электронной почты https://topdecorpro.ru…
          JW
          Jhon Wick1. Oktober 2024 22:52
          Indian Food Restaurant In Columbus OH| Layla’s Kitchen Indian Restaurant If you're looking for a truly authentic https://www.laylaskitchenrestaurantohio.com/ , Layla’s Kitchen Indian Restaurant is your go-to destination. Located at 6152 Cleveland Ave, Colu…
          КГ
          Кирилл Гусарев27. September 2024 16:09
          Не запускается программа на Qt: точка входа в процедуру не найдена в библиотеке DLL Написал программу на C++ Qt в Qt Creator, сбилдил Release с помощью MinGW 64-bit, бинарнику напихал dll-ки с помощью windeployqt.exe. При попытке запуска моей сбилженной программы выдаёт три оши…
          F
          Fynjy22. Juli 2024 11:15
          при создании qml проекта Kits есть но недоступны для выбора Поставил Qt Creator 11.0.2. Qt 6.4.3 При создании проекта Qml не могу выбрать Kits, они все недоступны, хотя настроены и при создании обычного Qt Widget приложения их можно выбрать. В чем может …

          Folgen Sie uns in sozialen Netzwerken