R
Rus6lan10 мая 2017 г. 6: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 г. 9: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

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

                Комментарии

                Только авторизованные пользователи могут публиковать комментарии.
                Пожалуйста, авторизуйтесь или зарегистрируйтесь
                e
                • ehot
                • 1 апреля 2024 г. 0:29

                C++ - Тест 003. Условия и циклы

                • Результат:78баллов,
                • Очки рейтинга2
                B

                C++ - Тест 002. Константы

                • Результат:16баллов,
                • Очки рейтинга-10
                B

                C++ - Тест 001. Первая программа и типы данных

                • Результат:46баллов,
                • Очки рейтинга-6
                Последние комментарии
                k
                kmssr9 февраля 2024 г. 5:43
                Qt Linux - Урок 001. Автозапуск Qt приложения под Linux как сделать автозапуск для флэтпака, который не даёт создавать файлы в ~/.config - вот это вопрос ))
                АК
                Анатолий Кононенко5 февраля 2024 г. 12:50
                Qt WinAPI - Урок 007. Работаем с ICMP Ping в Qt Без строки #include <QRegularExpressionValidator> в заголовочном файле не работает валидатор.
                EVA
                EVA25 декабря 2023 г. 21:30
                Boost - статическая линковка в CMake проекте под Windows Ошибка LNK1104 часто возникает, когда компоновщик не может найти или открыть файл библиотеки. В вашем случае, это файл libboost_locale-vc142-mt-gd-x64-1_74.lib из библиотеки Boost для C+…
                J
                JonnyJo25 декабря 2023 г. 19:38
                Boost - статическая линковка в CMake проекте под Windows Сделал всё по-как у вас, но выдаёт ошибку [build] LINK : fatal error LNK1104: не удается открыть файл "libboost_locale-vc142-mt-gd-x64-1_74.lib" Хоть убей, не могу понять в чём дел…
                G
                Gvozdik19 декабря 2023 г. 8:01
                Qt/C++ - Урок 056. Подключение библиотеки Boost в Qt для компиляторов MinGW и MSVC Для решения твой проблемы добавь в файл .pro строчку "LIBS += -lws2_32" она решит проблему , лично мне помогло.
                Сейчас обсуждают на форуме
                DA
                Dr Gangil Academics20 апреля 2024 г. 17:45
                Unlock Your Aesthetic Potential: Explore MSC in Facial Aesthetics and Cosmetology in India Embark on a transformative journey with an msc in facial aesthetics and cosmetology in india . Delve into the intricate world of beauty and rejuvenation, guided by expert faculty and …
                a
                a_vlasov14 апреля 2024 г. 16:41
                Мобильное приложение на C++Qt и бэкенд к нему на Django Rest Framework Евгений, добрый день! Такой вопрос. Верно ли следующее утверждение: Любое Android-приложение, написанное на Java/Kotlin чисто теоретически (пусть и с большими трудностями) можно написать и на C+…
                Павел Дорофеев
                Павел Дорофеев14 апреля 2024 г. 12:35
                QTableWidget с 2 заголовками Вот тут есть кастомный QTableView с многорядностью проект поддерживается, обращайтесь
                f
                fastrex4 апреля 2024 г. 14:47
                Вернуть старое поведение QComboBox, не менять индекс при resetModel Добрый день! У нас много проектов в которых используется QComboBox, в версии 5.5.1, когда модель испускает сигнал resetModel, currentIndex не менялся. В версии 5.15 при resetModel происходит try…
                P
                Pisych27 февраля 2023 г. 15:04
                Как получить в массив значения из связанной модели? Спасибо, разобрался:))

                Следите за нами в социальных сетях