■ QSettings Class 사용 이유

이번 포스팅에서는 QSettings Class에 대하여 알아보도록 하겠습니다.

사용자가 프로그램을 시작하기에 앞서 프로그램이 참조 해야하는 기본적인 정보가 필요할 경우가 있습니다.

 

예를 들면 프로그램에서 사용할 int 형, bool 형의 데이터일 수도 있고, GUI의 크기 정보나 배경의 색 혹은 한 시스템에서 여려 명의 사용자가 프로그램에 접근할 수 있는 구조에서 현재 어떤 사용자가 프로그램을 사용 중인지 등에 대한 정보가 필요한 경우입니다.

 

다양한 방법이 있을 수 있지만, Qt에서 제공하는 QSettings Class를 사용하면 간편하게 다양한 자료형의 Data에 접근하여 프로그램에서 사용 가능합니다. QSettings은 프로그램에서 설정한 경로와 해당 경로에 존재하는 파일을 통해 Data를 관리합니다.

경로를 따로 지정하지 않았을 때, Linux에서 Default 경로는 /root/.config 폴더입니다. 

 

settings("조직 명", "프로젝트 명")으로 구성하기 위해서는 Default 경로에 [조직 명] 폴더를 추가하고, [프로젝트 명.conf] 파일을 생성합니다. 아래의 예제에서 50번째 줄에 QSettings settings("TestPro", "InfoFile"); 으로 설정하였으므로,

InfoFile.conf의 위치는 /root/.config/TestPro/InfoFile.conf 입니다.

 

int형, bool형 Data 뿐만 아니라 QSize나 QPoint 등도 QVariant를 사용하기 때문에 저장이 가능합니다.

또한, mainwindow/size 및 pushbutton/point 등과 같이 사용하면 File에 Write할 경우 [mainwindow], [pushbutton] 등의 항목으로 자동 분류를 해줍니다. 자동 분류가 됨으로써 사용자는 다양한 Data를 더욱 간편하게 관리할 수 있습니다.

 

■ QSettings Class 상세 설명
사용자는 일반적으로 응용 프로그램이 세션 전체에서 설정 (창 크기 및 위치, 옵션 등)을 기억해야 합니다.

이 정보는 Windows의 경우 시스템 레지스트리 macOS 경우에는 iOS의 특성 목록 파일에 저장됩니다.

Unix 시스템에서 표준이없는 경우 많은 응용 프로그램 (KDE 응용 프로그램 포함)은 INI 텍스트 파일을 사용합니다.

 

QSettings는 이러한 기술에 대한 추상화 Class로 응용 프로그램 설정을 저장하고 복원 할 수 있습니다.

또한 사용자 지정 스토리지 형식을 지원합니다.

QSettings의 API는 QVariant를 기반으로 QString, QRect 및 QImage와 같은 대부분의 값을 저장할 수 있습니다.
비지속적 메모리 기반 구조만 있다면 QMap <QString, QVariant>을 대신 사용하는게 좋습니다.

■ QSettings Class 기본 사용
QSettings 객체를 생성 할 때는 회사 또는 조직 이름과 응용 프로그램 이름을 전달해야합니다. 

예를 들어, 제품 이름이 Star Runner이고 회사 이름이 MySoft인 경우 다음과 같이 QSettings 객체를 구성합니다.

    QSettings settings("MySoft", "Star Runner");


QSettings 객체는 스택 또는 힙에 생성할 수 있습니다. QSettings이 객체를 생성하고 파괴하는 것은 매우 빠릅니다.
어플리케이션의 여러 위치에서 QSettings를 사용하는 경우 QCoreApplication::setOrganizationName(), QCoreApplication::setApplicationName()을 사용하여 조직 이름 및 어플리케이션 이름을 지정한 다음 기본 QSettings 생성자를 사용할 수 있습니다.

    QCoreApplication::setOrganizationName("MySoft");
    QCoreApplication::setOrganizationDomain("mysoft.com");
    QCoreApplication::setApplicationName("Star Runner");
    ...

    QSettings settings;


QSettings는 설정을 저장합니다. 각 설정은 설정 이름 (키)을 지정하는 QString과 키와 관련된 데이터를 저장하는 QVariant로 구성됩니다. 

설정을 쓰려면 setValue()를 사용하십시오.

    settings.setValue("editor/wrapMargin", 68);


동일한 키를 가진 설정이 이미 존재하면 기존 값을 새 값으로 덮어 쓰고, 효율성을 위해 변경 사항이 영구 저장소에 즉시 저장되지 않을 수 있습니다. 항상 sync()를 호출하여 변경 사항을 커밋 할 수 있고, value()를 사용하여 설정 값을 다시 가져올 수 있습니다.

    int margin = settings.value("editor/wrapMargin").toInt();


지정된 이름의 설정이 없으면 QSettings는 null값을 가진 QVariant를 반환합니다.

value()에 두 번째 인수를 전달하여 다른 기본값을 지정할 수 있습니다.

    int margin = settings.value("editor/wrapMargin", 80).toInt();


주어진 키가 존재하는지 테스트하려면 contains(), 키와 관련된 설정을 제거하려면 remove()를 호출하십시오. 
모든 키 목록을 얻으려면 allKeys(), 모든 키를 제거하려면 clear ()를 호출하십시오.

■ QVariant 및 GUI 유형
QVariant는 Qt Core 모듈의 일부이므로 Qt GUI의 일부인 QColor, QImage 및 QPixmap과 같은 데이터 유형에 변환 기능을 제공 할 수 없습니다. 즉, QVariant에는 toColor (), toImage () 또는 toPixmap () 함수가 없습니다.

대신 QVariant::value () 템플릿 함수를 사용할 수 있습니다.

    QSettings settings("MySoft", "Star Runner");
    QColor color = settings.value("DataPump/bgcolor").value();


역변환 (예 : QColor에서 QVariant로)은 GUI 관련 유형을 포함하여 QVariant가 지원하는 모든 데이터 유형에 대해 자동으로 적용됩니다.

    QSettings settings("MySoft", "Star Runner");
    QColor color = palette().background().color();
    settings.setValue("DataPump/bgcolor", color);


qRegisterMetaType() 및 qRegisterMetaTypeStreamOperators()를 사용하여 등록된 사용자 정의 유형은 QSettings를 사용하여 저장할 수 있습니다.

 

■ 예제 소스 및 테스트 결과

// Source

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
 42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
// mainwindow.h
#ifndef MAINWINDOW_H
#define MAINWINDOW_H
 
#include <QMainWindow>
#include <QSettings>
#include <iostream>
 
namespace Ui {
class MainWindow;
}
 
class MainWindow : public QMainWindow
{
    Q_OBJECT
 
public:
    explicit MainWindow(QWidget *parent = 0);
    ~MainWindow();
    void ReadFile();
    void WriteFile();
 
private:
    Ui::MainWindow *ui;
};
 
#endif // MAINWINDOW_H
 
 
// mainwindow.cpp
#include "mainwindow.h"
#include "ui_mainwindow.h"
 
MainWindow::MainWindow(QWidget *parent) :
    QMainWindow(parent),
    ui(new Ui::MainWindow)
{
    ui->setupUi(this);
    WriteFile();
    ReadFile();
}
 
MainWindow::~MainWindow()
{
    delete ui;
}
 
void MainWindow::ReadFile()
{
    QSettings settings("TestPro""InfoFile");
    int r_fileData = 0;
    bool r_fileFlag = false;
    QSize r_windowSize;
    QPoint r_buttonPoint;
 
    r_fileData = settings.value("File_Integer_Data").toInt();
    r_fileFlag = settings.value("File_Boolean_Data").toBool();
    r_windowSize = settings.value("mainwindow/size").toSize();
    r_buttonPoint = settings.value("pushbutton/point").toPoint();
 
    QString firstLine;
    firstLine.sprintf("File_Integer_Data: %d\n", r_fileData);
 
    QString secondLine;
    secondLine.sprintf("File_Boolean_Data: %s\n" , (r_fileFlag) ? "true" : "false");
 
    QString thirdLine;
    thirdLine.sprintf("Window_Size_Data: %d %d\n" , r_windowSize.width(), r_windowSize.height());
 
    QString fourthLine;
    fourthLine.sprintf("Button_Point_Data: %d %d\n" , r_buttonPoint.x(), r_buttonPoint.y());
 
    ui->textBrowser->insertPlainText(firstLine);
    ui->textBrowser->insertPlainText(secondLine);
    ui->textBrowser->insertPlainText(thirdLine);
    ui->textBrowser->insertPlainText(fourthLine);
}
 
void MainWindow::WriteFile()
{
    QSettings settings("TestPro""InfoFile");
    int w_fileData = 1;
    bool w_fileFlag = true;
 
    settings.setValue("File_Integer_Data", w_fileData);
    settings.setValue("File_Boolean_Data", w_fileFlag);
    settings.setValue("mainwindow/size"this->size());
    settings.setValue("pushbutton/point", QPoint(ui->testButton->x(), ui->testButton->y()));
}

 

// File Location 및 File Data

 

//  Result Image