I need to use filepath as a section name in ini file and I try to do it like this:
QSettings ini(iniPath, QSettings::IniFormat);
ini.beginGroup("C:\\Users\\Username\\Documents\\222.txt");
ini.setValue(attributeName, attributeValue);
...
ini.endGroup();
Then I try to read values from this section:
QSettings ini(iniPath, QSettings::IniFormat);
ini.beginGroup("C:\\Users\\Username\\Documents\\222.txt");
auto allKeys = ini.allKeys();
for (auto& key: allKeys)
{
QString val = ini.value(key);
...
}
ini.endGroup();
But in the output file I can see just "[C%3AUsers%5CUsername%5CDocuments%5C222.txt]" as name of section. And most importantly that QSettings can't find this section when reads ini file, allKeys variable is always empty.
What could be the problem? Thanks.
Look at the QSettings::Format documentation:
QSettings always treats backslash as a special character and provides no API for reading or writing such entries.
Use QDir::fromNativeSeparators() for the section name. When you read back, just use the path as is (all Qt classes support it) or covert it to the Windows-style with QDir::toNativeSeparators().
It was my mistake. The code in my question is a little bit simplified. Code for writing and reading is located in methods "save" and "load". I Feel myself rather silly :( The problem was in the difference between input parameters in "save" and "load" methods. In "save" method input string was "C:\Users\Username\Documents\222.txt" and in "load" method it was "C:/Users/Username/Documents/222.txt" so when I tried to read the settings in "load" method QSettings didn't can find the section.
As I understand it QSettings escapes special characters like "\" with "%" symbol. And "/" symbol QSettings uses for making nestings. So I decide to use paths like "C:\Users\Username\Documents\222.txt" as is. It works fine. Thank you all.
Related
Aloha,
Im developing a small "ServerManager" for myself using QT (C++).
Anything worked till this point:
I use QSettings to store all relevant Settings (like Server, installed Plugins and so on).
As I didn't want to instanciate the QSettings class everywhere I have to use it, i thought i could try to instanciate it one time in the main.cpp and make it available using the qApp->setProperty() method.
How i setup the QSettings class:
QSettings* Settings = new QSettings(".\\Settings.ini", QSettings::IniFormat);
How i "publish" it:
qApp->setProperty("Settings", QVariant::fromValue<QSettings*>(Settings));
And finally. If i use it like this:
QSettings* Settings = qApp->property("Settings").value<QSettings*>();
Settings->beginGroup("Servers");
The whole application crashed with an SIGSEGV signal (Segmentation fault).
Stacktrace: Stacktrace http://host-it.tk/Upload/53ab11da0d706/37.PNG
I really got no clue why this happens.
Maybe the solution is obvious, but this is my "first real" Application.
It seems like I got the well known "tunnel view".
Thanks for your time!
Relevant code parts: http://pastebin.com/VzZ9uuJi
QT-Version: 5.2.1
Since a QSettings* is not a usual QVariant type, you would have to declare it.
Q_DECLARE_METATYPE(QSettings*);
This is not the usual way to share QSettings, though. Since it is in INI format, consider just passing the location to the INI file with absolute paths instead:
QFileInfo path(".\\Settings.ini");
qApp->setProperty("SettingsLocation", path.absoluteFilePath());
Then later:
QSettings Settings(qApp->property("SettingsLocation").toString(), QSettings::IniFormat);
Settings.beginGroup("Servers");
I'm an unfortunate beginner at C++ and using the Qt GUI designer program seemed perfect for my needs, except I'm having problems trying to write out the code necessary for this. I could use the QSettings string to store local settings on the hard drive, but I personally hate it when programs do the %HOME_LOCAL%\APPS_SETTINGS bull that some do. I need to save a text file for both settings and a local\host database, within the program directory, to remember strings to read from later.
What is the line of code I need to make use of a local host text database or is there a better option? And how can I store that with the local program inside its directory?
You can use QSettings with any file, with constructor QSettings::QSettings ( const QString & fileName, Format format, QObject * parent = 0 ).
To get the program directory, you can use QCoreApplication::applicationDirPath().
So, answer to your question, statement to put after creation of QApplication instance:
QSettings *settings = new QSettings(
QCoreApplication::applicationDirPath() + "/settings.ini",
QSettings::IniFormat,
qApp);
But, as noted in the comments under question, if you're making your program for general distribution, you should use the OS default. Examine all the constructors of QSettings to see what it can do. User does not often have write permission in the application directory. Note that you can also store settings to Windows registry with QSettings::NativeFormat.
Im trying to create ini file that will hold me the configuration data, I have singletone class
that setting the QSettings object like this :
... #DEFINE CONFIG_FILE_NAME "myconfig.ini"
m_pSettings = new QSettings(QDir::currentPath()+"/"+CONFIG_FILE_NAME,QSettings::IniFormat);
this is accourding the document, but when i look in my application dir, there is none myconfig.ini file created, what im doing wrong ?
I believe in order to force QSettings file to appear you would need to set at least one value in it and then call sync() method. See if an example below would work for you:
QSettings* settings = new QSettings(QDir::currentPath() + "/my_config_file.ini", QSettings::IniFormat);
settings->setValue("test", "value");
settings->sync();
hope this helps, regards
I dont think that "/"+CONFIG_FILE_NAME return the expected result. May be the cause of your problem..
Anyway operator +() is present in QString class so QDir::currentPath() + "/my_config_file.ini" must work fine.
I have set a file to be read-only (right click and check readonly). Now when I try to remove the file using the function bool QDir::remove(const QString & fileName) the file is not removed and false is returned.
How do I proceed with this? I have tried fiddling around by changing the permission of the file using QFile::setPermission, but that returns false too.
Can anybody advise an approach for the same?
file.setPermissions(QFile::ReadOther | QFile::WriteOther);
file.remove();
should work.
You can set file permissions with QFile
Of course this only for files you have user permission to do. The error may also be because the file is open in another app
First, have you checked QFile::error() to see why the file wasn't removed?
Second, in the event that you're still not getting a useful error message back, you could check the source to find out if you can get more information. Checking the source reveals the following, for example:
QFile::remove() uses the underlying file engine to do the removal. That file engine is platform specific and in qfsfileengine_win.cpp for windows. Line 830 shows that it's using DeleteFile to do the removal so you might be able to get more information by calling GetLastError, though I'd hope that Qt translates the error message appropriately.
QDir::remove() function is not a static function. so you can create QDir with parent file path and call then remove it:
QDir dir(parent's directory);
and then
dir.remove(fileName);
I think you should use this:
bool QFile::remove ( const QString & fileName ) [static]
instead of this:
QDir::remove ( const QString & fileName )
Have you tried to use bool QFile::remove(const QString &fileName)?
linux: $HOME/.config
windows: %APPDATA%
mac os: $HOME/.config
It can be set using http://qt-project.org/doc/qt-4.8/qsettings.html#setPath, but it seems as I am not able to retrieve it.
http://qt-project.org/doc/qt-4.8/qlibraryinfo.html#location QLibraryInfo::LibrariesPath returns the system wide settings dir, which is not what I want.
Any ideas, or do I have to code it separately for each platform?
€: I want to create a sub directory, and store files into it. (You may punish me if this is a bad idea)
This might not answer your question directly: if you want to store per-user persistent data, shouldn't you use QDesktopServices::storageLocation(QDesktopServices::DataLocation) instead?
This is a nasty workaround. First you create QSettings, then get its location.
QSettings cfg(QSettings::IniFormat, QSettings::UserScope,
"organization", "application");
QString config_dir = QFileInfo(cfg.fileName()).absolutePath() + "/";
Credits go to the Qt Centre forum.
QSettings stores the default config in the user AppData directory. See documentation for QSettings. Also this code instructs to store the config in the Ini file format.
this works on both qt 4 and qt 5
QApplication::setApplicationName("MyApp");
QApplication::setOrganizationName("Me");
QString homePath;
#if QT_VERSION >= 0x050000
homePath = QStandardPaths::writableLocation(QStandardPaths::DataLocation);
#else
homePath = QDesktopServices::storageLocation(QDesktopServices::DataLocation);
#endif
Why do you need to know the settings path? If you are going to put settings in it, you could use QSettings. I could see making a subdirectory to hold various settings, but it seems like the easiest way would be to use QSettings directly.
As far as I can tell, you can't retrieve the path. In the Qt source, src/corelib/io/qsettings.cpp, there is a function to get the path:
static QString getPath(QSettings::Format format, QSettings::Scope scope)
{
...
but it's not accessible from code using Qt. You can't copy it and use it either, because it uses internal Qt globals to store the path...
EDIT: A solution was posted, using QDesktopServices.storageLocation(QDesktopServices.DataLocation) but it doesn't do exactly what the question was asking for, i.e. if I set a custom path using QSettings.setPath() it doesn't reflect the change.
What platform are you at?
Might be related or not but in windows, the default is to write QSettings to the registry.
I read more into the question than there was as it was originally posted. It is clearer after the edits. Ok, so can't you use..
QString QSettings::fileName () const
Returns the path where settings are written to using this QSettings object are stored.
On Windows, if the format is QSettings::NativeFormat, the return value is a system registry path, not a file path.