R
Rus6lan10 травня 2017 р. 06:57

Области видимости

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

#ifndef SETTINGS_H
#define SETTINGS_H

#include <Headers/ModBusUSB.h>
#include <QSettings>


class settingsClass
{
public:
    TConfigUSBPort configUSBDevice;
    int tresHold;
    settingsClass() {}
};
void readSettings(settingsClass &settingsDiesel);


#endif // SETTINGS_H
#include <Headers/settings.h>


settingsClass settingsDiesel;

void readSettings(settingsClass &settingsDiesel){
    QSettings *settings;
    settings = new QSettings;
    settingsDiesel.configUSBDevice.adc_count = settings->value("count").toInt();
    settingsDiesel.configUSBDevice.adc_freq = settings->value("freq").toInt();
    settingsDiesel.configUSBDevice.pid = settings->value("PID").toInt();
    settingsDiesel.configUSBDevice.vid = settings->value("VID").toInt();
    settingsDiesel.configUSBDevice.timeOut = settings->value("timeout").toInt();
    settingsDiesel.tresHold = settings->value("treshold").toInt();
}
Вот settings.h и .cpp, но объект settingsDiesel не доступен в widgetSettings Заголовок settings.h подключен в widgetSettings.h
#include <Headers/widgetsettings.h>
#include "ui_widgetsettings.h"

widgetSettings::widgetSettings(QWidget *parent) :
    QWidget(parent),
    ui(new Ui::widgetSettings)
{
    ui->setupUi(this);
    QRegExp pid("[1-9]\\d{0,3}");
    QValidator *validatorPID = new QRegExpValidator(pid, this);

    ui->lineEditPID->setValidator(validatorPID);
    ui->lineEditVID->setValidator(validatorPID);
    ui->spinBoxCount->setMaximum(MAX_COUNT_ADC);
}



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

void widgetSettings::on_pushButtonAccept_clicked()
{
    QSettings settings(ORGANIZATION_NAME, APPLICATION_NAME);
    bool ok;
    auto PID = QString("0x" + ui->lineEditPID->text()).toInt(&ok, 16);
    auto VID = QString("0x" + ui->lineEditVID->text()).toInt(&ok, 16);
    settings.setValue("PID", PID);
    settings.setValue("VID", VID);
    settings.setValue("timeout", ui->spinBoxTimeout->value());
    settings.setValue("freq", ui->spinBoxFreq->value());
    settings.setValue("count", ui->spinBoxCount->value());
    settings.setValue("treshold",ui->spinBoxTreshold->value());
    settings.sync();
}

structure.png
Рекомендуємо хостинг TIMEWEB
Рекомендуємо хостинг TIMEWEB
Стабільний хостинг, на якому розміщується соціальна мережа EVILEG. Для проектів на Django радимо VDS хостинг.

Вам це подобається? Поділіться в соціальних мережах!

7
Evgenii Legotckoi
  • 10 травня 2017 р. 10:36

Итак. Первое, что стоит учитывать, это то, что если в функции main прописать следующее:

int main(int argc, char *argv[])
{
    QApplication a(argc, argv);
    QCoreApplication::setOrganizationName( "ORGANIZATION" );
    QCoreApplication::setApplicationName( "APP NAME" );
    QCoreApplication::setApplicationVersion( APP_VERSION );

    MainWindow w;
    w.show();

    return a.exec();
}

то тогда не нужно будет каждый раз писать так

QSettings settings(ORGANIZATION_NAME, APPLICATION_NAME);

Достаточно будет записи

QSettings settings;

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

Но если имеется необходимость всё вывести в единый класс, который отвечал бы за настройки, то возможно имеет смысл использовать статические методы и даже... может быть синглтон.

Тогда сохранение настроек в диалоге настроек может выглядеть так:

void ConfigDialog::saveSettings()
{
    SettingsHelper::setCustomProjectsDirectory(ui->buildPage->isCustomDirectory());
    SettingsHelper::setPathCustomProjectsDirectory(ui->buildPage->getPathDirectory());
    emit settingsUpdated();
}

А сами эти методы могут выглядеть так:

Заголовочный файл:
class SettingsHelper
{
    static const QString CUSTOM_PROJECT_DIRECTORY;
    static const QString CUSTOM_PROJECT_DIRECTORY;

public:
    static void setCustomProjectsDirectory(const bool value);
    static void setPathCustomProjectsDirectory(const QString value);

    static bool isCustomProjectsDirectory();
    static QString getPathCustomProjectsDirectory();
};
Файл реализации:
const QString SettingsHelper::CUSTOM_PROJECT_DIRECTORY = "build_and_run/customProjectsDirectory";
const QString SettingsHelper::PATH_PROJECT_DIRECTORY = "build_and_run/pathProjectsDirectory";

void SettingsHelper::setCustomProjectsDirectory(const bool value)
{
    QSettings settings;
    settings.setValue(CUSTOM_PROJECT_DIRECTORY, value);
    settings.sync();
}

void SettingsHelper::setPathCustomProjectsDirectory(const QString value)
{
    QSettings settings;
    settings.setValue(PATH_PROJECT_DIRECTORY, value);
    settings.sync();
}

bool SettingsHelper::isCustomProjectsDirectory()
{
    QSettings settings;
    return settings.value(CUSTOM_PROJECT_DIRECTORY, false).toBool();
}

QString SettingsHelper::getPathCustomProjectsDirectory()
{
    QSettings settings;
    return settings.value(PATH_PROJECT_DIRECTORY, qApp->applicationDirPath()).toString();
}

Таким образом с помощью статических методов можно будет дергать параметры в любом месте программы и когда захочется. Достаточно будет добавить в нужном файле заголовочный файл stylehelper.h и воспользоваться статическими методами для получения необходимых настроек.

    R
    • 10 травня 2017 р. 15:18

    То есть для каждого значения(переменной), которое я хочу сохранить, надо реализовать статик-методы get и set? Я правильно понял? В синглтон пока рано лезть, хотя я тоже про него думал (прочитал в одной книжке и подумал, что это то, что мне надо).

      R
      • 10 травня 2017 р. 15:30

      У QSettings оказывается тоже есть статик-методы

      QSettings::setValue("VID", VID);
      QSettings::value("PID").toInt();
      . Может можно просто их использовать
        Evgenii Legotckoi
        • 10 травня 2017 р. 23:29

        Конечно, можно и эти методы использовать. Вообще, всё зависит от задачи. Если нужно дёрнуть одно значение, то можно и статическими методами QSettings воспользоваться. Если нужно брать пачку значений для какого-то специального объекта, то можно сделать обёртку с методом, который будет принимать в качестве аргумента ссылку или указатель на данный объект и добавлять в него все необходимые объекты.

          R
          • 13 травня 2017 р. 09:20

          Решил все таки сделать синглтон, я только не очень понимаю, где именно его создать, чтобы был доступ по всей программе?

            Evgenii Legotckoi
            • 13 травня 2017 р. 12:37
            • Відповідь була позначена як рішення.

            Тут надо понимать, что такое Singleton (одиночка). Под синглтоном подразумевается класс, который имеет в программе только один экземпляр, который создаётся при первом обращении к нему, применительно к C++. Раз экземпляр в программе только один, значит объект в данном случае должен объявляться как static и обращение к нему должно быть сделано через статический метод. Например, можно использовать Синглтон Меерса

            #ifndef SINGLETONCLASS_H
            #define SINGLETONCLASS_H
            
            class SingletonClass
            {
            public:
                int getSomeInfo()
                {
                    return 10;
                }
            
                static SingletonClass& instance()
                {
                    static SingletonClass instance;
                    return instance;
                }
            
            private:
                SingletonClass(){}
            };
            
            #endif // SINGLETONCLASS_H

            В данном случае получение экземпляра класса всегда должно осуществляться через статический метод SingletonClass::instance() Все остальные методы могут быть не статическими. А применять его можно будет абсолютно везде, где будет подключён его заголовочный файл.

            #include "widget.h"
            #include <QApplication>
            #include <QDebug>
            
            #include "singletonclass.h"
            
            int main(int argc, char *argv[])
            {
                QApplication a(argc, argv);
                // Обращение к синглтону и его методу
                qDebug() << SingletonClass::instance().getSomeInfo();
            
                Widget w;
                w.show();
            
                return a.exec();
            }

            Только нужно поосторожнее работать с этим паттерном проектирования, поскольку иногда от него могут быть только проблемы. Особенно, если в какой-то момент понадобится иметь два и более экземпляров этого класса. Например, для нескольких настроек софта, которые могут быть применены для разных открытых документов. Перекраивать в таком случае крупный проект будет весьма затратно.

              R
              • 13 травня 2017 р. 13:02

              Я вроде все понял. Спасибо большое.

                Коментарі

                Only authorized users can post comments.
                Please, Log in or Sign up
                AD

                C++ - Тест 004. Указатели, Массивы и Циклы

                • Результат:50бали,
                • Рейтинг балів-4
                m
                • molni99
                • 26 жовтня 2024 р. 11:37

                C++ - Тест 004. Указатели, Массивы и Циклы

                • Результат:80бали,
                • Рейтинг балів4
                m
                • molni99
                • 26 жовтня 2024 р. 11:29

                C++ - Тест 004. Указатели, Массивы и Циклы

                • Результат:20бали,
                • Рейтинг балів-10
                Останні коментарі
                ИМ
                Игорь Максимов22 листопада 2024 р. 22:51
                Django - Підручник 017. Налаштуйте сторінку входу до Django Добрый вечер Евгений! Я сделал себе авторизацию аналогичную вашей, все работает, кроме возврата к предидущей странице. Редеректит всегда на главную, хотя в логах сервера вижу запросы на правильн…
                Evgenii Legotckoi
                Evgenii Legotckoi01 листопада 2024 р. 00:37
                Django - Урок 064. Як написати розширення для Python Markdown Добрый день. Да, можно. Либо через такие же плагины, либо с постобработкой через python библиотеку Beautiful Soup
                A
                ALO1ZE19 жовтня 2024 р. 18:19
                Читалка файлів fb3 на Qt Creator Подскажите как это запустить? Я не шарю в программировании и кодинге. Скачал и установаил Qt, но куча ошибок выдается и не запустить. А очень надо fb3 переконвертировать в html
                ИМ
                Игорь Максимов05 жовтня 2024 р. 17:51
                Django - Урок 064. Як написати розширення для Python Markdown Приветствую Евгений! У меня вопрос. Можно ли вставлять свои классы в разметку редактора markdown? Допустим имея стандартную разметку: <ul> <li></li> <li></l…
                d
                dblas505 липня 2024 р. 21:02
                QML - Урок 016. База даних SQLite та робота з нею в QML Qt Здравствуйте, возникает такая проблема (я новичок): ApplicationWindow неизвестный элемент. (М300) для TextField и Button аналогично. Могу предположить, что из-за более новой верси…
                Тепер обговоріть на форумі
                Evgenii Legotckoi
                Evgenii Legotckoi25 червня 2024 р. 01:11
                добавить qlineseries в функции Я тут. Работы оень много. Отправил его в бан.
                t
                tonypeachey115 листопада 2024 р. 17:04
                google domain [url=https://google.com/]domain[/url] domain [http://www.example.com link title]
                NSProject
                NSProject04 червня 2022 р. 13:49
                Всё ещё разбираюсь с кешем. В следствии прочтения данной статьи. Я принял для себя решение сделать кеширование свойств менеджера модели LikeDislike. И так как установка evileg_core для меня не была возможна, ибо он писался…
                9
                9Anonim25 жовтня 2024 р. 19:10
                Машина тьюринга // Начальное состояние 0 0, ,<,1 // Переход в состояние 1 при пустом символе 0,0,>,0 // Остаемся в состоянии 0, двигаясь вправо при встрече 0 0,1,>…

                Слідкуйте за нами в соціальних мережах