2016-10-28 6 views
0

Windows7에서 Qt5.7을 사용하고 있습니다. 내 현재 응용 프로그램에서
, 나는 내 자신의 설정 관리자 클래스가, 그 다음과 같습니다Qt : 응용 프로그램/실행 가능 디렉토리에서 설정 ini 파일을 가져 오는 데 문제가 있습니다.

헤더 :

class SettingsManager 
{ 
public: 
    void  write(const QString & key, const QVariant & variant); 
    QVariant read (const QString & key) const; 

private: 
    static QSettings settings; 
}; 

소스 CPP를 :

QSettings SettingsManager::settings("settings.ini", QSettings::IniFormat); 

void SettingsManager::write(const QString & key, const QVariant & variant) 
{ 
    settings.setValue(key, variant); 
} 

QVariant SettingsManager::read(const QString & key) const 
{ 
    return settings.value(key); 
} 

내 문제입니다 : 나는 몇몇 친구에게 앱을 주었고 아마 다른 작업 디렉토리 나 다른 것으로 시작했다. 그리고 앱은를 찾지 못했다.파일이므로 작동하지 않습니다.

그래서 질문은 : 위의 코드를 수정하여 응용 프로그램/실행 가능 디렉토리에서 settings.ini 파일을 가져올 수 있습니까? 분명히 settings.ini 파일은 항상 앱 자체와 동일한 폴더에 있습니다.

+0

절대 경로를 사용하고있는 것 같지 않습니다. – dtech

+0

'(QCoreApplication :: applicationDirPath() + "/settings.ini")'와 같은 것을 시도했지만 작동하지 않았습니다. 그것은 다음과 같았습니다 : _QApplication 객체를 처음에 인스턴스화하십시오 _... –

+0

어딘가에'QApplication' 또는'QCoreApplication'이 있어야합니다. 정적 함수를 호출하기 전에 먼저 객체를 만들어야합니다. 어쨌든 하나 만들어야 만 큰일이 아니어야합니다. – Hayt

답변

2

모든 정적 데이터 멤버. SettingsManager()::read(...)처럼 사용하고 계십니까? 네임 스페이스 또는 싱글 톤 패턴에서 함수를 사용하는 것이 더 적절할 수 있습니다.

어쨌든, 질문에, 당신은 QApplication::applicationDirPath()이 목적으로 사용할 수 있습니다. 그것은 응용 프로그램 바이너리가 들어있는 디렉토리에 대한 절대 경로를 가져옵니다. 예 :

QString absPath = QDir(QApplication::applicationDirPath()).filePath("settings.ini");  

은 원하는 위치로 절대 경로를 가져옵니다.

편집 : - "의 QApplication은 오류가 존재하지 않습니다"당신이 주요 들어가기 전에 실행되는 글로벌 정적 초기화, 그것을 사용하고 있기 때문에 당신이 가진 문제를 가지고있는 것처럼

보인다 대해 의견을 응답()이므로 아직 QApplication이 없습니다. 정적 함수 변수를 사용하여 함수가 호출 될 때까지 초기화를 지연시킬 수 있습니다.

싱글 톤 SettingsManager를 만들거나 QSettings 만 선택할 수 있습니다. (위에서 말했듯이 QSettings가 아마도 더 이상하다고 생각합니다.) QSettings 싱글의

예 : (A cpp에있는 정의 할 필요가있다)

QSettings& globalInstance() { 
    static QSettings settings(QDir(QApplication::applicationDirPath()).filePath("settings.ini")); 
    return settings; 
} 

당신이 당신의 기능에, 그것은 늘 당신이 함수를 호출 한 때까지 QSettings를 만들고, 거기에 의지 그때 것을 사용하는 경우 QApplication 인스턴스 여야합니다.

settingsmanager.h :

#include <QApplication> 
#include <QDir> 
#include <QSettings> 

class SettingsManager 
{ 
public: 
    SettingsManager & instance(); 

    void  write(const QString & key, const QVariant & variant); 
    QVariant read (const QString & key) const; 

private: 
    SettingsManager(const QString & path) : 
     settings(path, QSettings::IniFormat) 
    {} 

    QSettings settings; 
}; 

settingsmanager.cpp :

#include "settingsmanager.h" 

SettingsManager& SettingsManager::instance() { 
    static SettingsManager s(QDir(QApplication::applicationDirPath()).filePath("settings.ini")); 
    return s; 
} 

void SettingsManager::write(const QString & key, const QVariant & variant) 
{ 
    settings.setValue(key, variant); 
} 

QVariant SettingsManager::read(const QString & key) const 
{ 
    return settings.value(key); 
} 

사용 :

auto val = SettingsManager::instance().read("key"); 
+0

나는 보통 'ClassName :: instance()'와 같은 모든 것을 피하려고한다. 싱글 톤이나 그런 맛을 좋아하지 않는다. (C++의 이상 함). 나는 가능하다면 대신 monostate를 선호한다 - 적어도 C++처럼 보인다. 그렇다고해서 내가 생각/제안하는 것을 반대하지 않는다는 의미는 아닙니다. 엄지 손가락/투표까지! 고마워요. :) –

+0

이 경우에는'namespace Settings {read (..); 쓰다(..); }'를 사용하고 전역 QSettings 인스턴스 기능에 대해 cpp에서 익명의 네임 스페이스를 사용하십시오. 그런 식으로, 인터페이스는'Settings :: read ("key")'일 것입니다. 훨씬 더 깨끗해 보입니다. 또는 클래스 외부의 인스턴스 함수, 즉 settings()를 만드십시오.읽기 ("키"); –

+0

upvote btw 주셔서 감사합니다, 내 첫 번째 :) –

1

응용 프로그램과 함께 ini 파일을 보내지 마십시오. 사용자가 응용 프로그램을 처음 실행하면 응용 프로그램에서 ini 파일을 만듭니다. 설정을 읽을 때 항상 기본값을 설정해야합니다. 나중에 사용하기 위해 사용자는 기본값을 무시하고 저장된 설정을 사용합니다.

변경하여 읽기 기능 :

QVariant SettingsManager::read(const QString & key, const QVariant &defaultValue) const 
{ 
    return settings.value(key,defaultValue); 
} 

하고 함수를 호출 할 때마다 항상 기본 가치를 제공을

모든 비 정적 멤버 함수와 객체를보고 조금 이상한 것 같다
+0

정확히 내가 원하는 것은 아니지만 향후 개발에 유용 할 수도 있습니다. Thumb up :) –

2
하지만 전체 클래스 싱글을 선호하는 것

설정을 지정할 수 있습니다 그래서 QSettings::setPath

QSettings::setPath(QSettings::IniFormat,QSettings::SystemScope, 
        QCoreApplication::applicationDirPath()); 

와 경로는 트릭을해야한다.

당신이 하나를 가지고 있기 때문에 INI는 것이 아니라 사용자 기반에 따라 내가 SystemScope 여기에 적절한 생각 파일

참고 : 이것은을위한 프로그램에 Qt는이 모든 INI 파일을 찾는이의 위치를 ​​설정합니다 SystemScope 여러 ini 파일 위치를 원할 경우이 파일을 사용하지 마십시오 SystemScope

+0

사실 앱에는 다른 4 INI 파일이 있지만 다른 하위 폴더에 있습니다 (일부 입력 데이터 파일의 최신 버전을 얻는 데 사용됨). 솔루션/아이디어가 있다면 어떻게 영향을 미칩니 까? 어쨌든, 당신의 아이디어를 공유하기위한 thx. 엄지 척! :) –

+0

이것은 Qt가 ini 파일을 찾는 경로를 바꿀 수 있습니다. 하지만 어쨌든 내가 말하고자하는 한 곳에 파일을 두어야합니다. (또는 사용자 별 구성에 대해 다른 시스템 파일을 한 곳에서) – Hayt

+0

기존 INI 파일을 조합 할 수 없습니다. 하지만 그들은 여전히 ​​경로와 파일 이름을 지정하는 것과 같이 명시 적으로 액세스 할 수 있다고 생각합니다 ...? 나는 위의'QSetting :: setPath' 등을 어떻게 든 방해하지 않고서도 의미한다. –