I am currently attempting to create a new directory and create a new file inside of this directory. However, QDir recognizes that this file exists, however when I try to cd to my new directory, the currentPath returns the same value before and after the QDir().cd(dirName)
QDir().cdUp();
if(!QDir(dirName).exists())
QDir().mkdir(dirName);
qDebug() << QDir().currentPath(); // returns a path up from exe dir
if(QDir().cd(dirName))
qDebug() << QDir().currentPath(); //returns the same path as above
Really not sure why this isn't working, I am pretty new to programming and was wondering why this was.
QDir().cd(dirName)
Every time you perform QDir() you're creating a new instance of the object, then you perform an operation on it (i.e., .cd(dirName)), and finally that object goes out of scope and is destroyed; thereby losing all your changes.
Instead you should be creating a single instance and performing all operations on it.
QDir dir;
dir.cd(dirName);
dir.path();
The constructor QDir() creates a QDir object pointing to the program's working directory. QDir()::cd() changes that QDir object directory, however it does not change program directory. If you really want to change current application working directory, see QDir()::setCurrent(const QString & path)
That current application directory is used as relative path for files. So, to create a file in a new directory, you can specify the full file path or to use relative path as:
QDir::setCurrent(new_base_path);
QFile("some_relative_file_name");
...
Related
I have this code in QT c++
void writeInFile()
{
QFile file(":/texts/test.txt");
if(file.open(QIODevice::ReadWrite))
{
QTextStream in(&file);
in<<"test";
}
file.close();
}
I want to add "test" to my text file which is in resources with prefix "texts", but this function does nothing, I can't write or read from file when I am oppening it with "QIODevice::ReadWrite" or "QFile::ReadWrite", I can only read from it on readonly mode. Any help or advice welcome.
Qt resource files are read-only, as they are put into the binary as "code" - and the application cannot modify itself.
Since editing resources is simply impossible, you should follow the standard approach of caching those files. This means you copy the resource to the local computer and edit that one.
Here is a basic function that does exactly that:
QString cachedResource(const QString &resPath) {
// not a ressource -> done
if(!resPath.startsWith(":"))
return resPath;
// the cache directory of your app
auto resDir = QStandardPaths::writableLocation(QStandardPaths::CacheLocation);
auto subPath = resDir + "/resources" + resPath.mid(1); // cache folder plus resource without the leading :
if(QFile::exists(subPath)) // file exists -> done
return subPath;
if(!QFileInfo(subPath).dir().mkpath("."))
return {}; //failed to create dir
if(!QFile::copy(resPath, subPath))
return {}; //failed to copy file
// make the copied file writable
QFile::setPermissions(subPath, QFileDevice::ReadUser | QFileDevice::WriteUser);
return subPath;
}
In short, it copies the resource to a cache location if it does not already exist there and returns the path to that cached resource. One thing to be aware of is that the copy operation presevers the "read-only" permission, which means we have to set permissions manually. If you need different permissions (i.e. execute, or access for the group/all) you can adjust that line.
In your code, you would change the line:
QFile file(cachedResource(":/texts/test.txt"));
My qt project has .qrc file so my resources files are stored like ":/audio/melody/...".
I need to choose which files to use or not in runtime, so my program stores the resources path in .txt file.
In runtime, my program get these path to string, as variables.
So now I need to use these variables to put [setSource(variables)] methods of any other Qt objects. But it can't.
I tried to convert std::string (which has the file path) to QString, and put it in QtObj.setSource() as QUrl(QString).
But I found the QUrl(QString) has no data(I expected that there was resource path like ":/audio/melody/.. blahblah" in QUrl(QString)).
How can I convert the std::string(which has resource path) to QUrl, in order to use it as a resource path?
Actually, I wonder there is possibility to use resource path as variables.
To get a list of all resources, the files itself and a URL to the file at runtime you can do this:
QHash<QUrl, QFile> list;
QDirIterator it(":", QDirIterator::Subdirectories);
while (it.hasNext()) {
QFile file(it.next());
QUrl url = QUrl::fromLocalFile(file.fileName())
list.insert(url, file);
}
I have this code in QT c++
void writeInFile()
{
QFile file(":/texts/test.txt");
if(file.open(QIODevice::ReadWrite))
{
QTextStream in(&file);
in<<"test";
}
file.close();
}
I want to add "test" to my text file which is in resources with prefix "texts", but this function does nothing, I can't write or read from file when I am oppening it with "QIODevice::ReadWrite" or "QFile::ReadWrite", I can only read from it on readonly mode. Any help or advice welcome.
Qt resource files are read-only, as they are put into the binary as "code" - and the application cannot modify itself.
Since editing resources is simply impossible, you should follow the standard approach of caching those files. This means you copy the resource to the local computer and edit that one.
Here is a basic function that does exactly that:
QString cachedResource(const QString &resPath) {
// not a ressource -> done
if(!resPath.startsWith(":"))
return resPath;
// the cache directory of your app
auto resDir = QStandardPaths::writableLocation(QStandardPaths::CacheLocation);
auto subPath = resDir + "/resources" + resPath.mid(1); // cache folder plus resource without the leading :
if(QFile::exists(subPath)) // file exists -> done
return subPath;
if(!QFileInfo(subPath).dir().mkpath("."))
return {}; //failed to create dir
if(!QFile::copy(resPath, subPath))
return {}; //failed to copy file
// make the copied file writable
QFile::setPermissions(subPath, QFileDevice::ReadUser | QFileDevice::WriteUser);
return subPath;
}
In short, it copies the resource to a cache location if it does not already exist there and returns the path to that cached resource. One thing to be aware of is that the copy operation presevers the "read-only" permission, which means we have to set permissions manually. If you need different permissions (i.e. execute, or access for the group/all) you can adjust that line.
In your code, you would change the line:
QFile file(cachedResource(":/texts/test.txt"));
There's probably a simple solution to this but I just can't find it.
When I open my application I want to open an sqlite database one directory up from the current directory the program is running from. It is the 'Database' directory.
This is the relevant lines of code. Nothing else matters at this point.
The database doesn't open. Don't want to create a database, I want to use an existing one.
string d_base = "Database/settings.db";
if(SQLITE_OK == sqlite3_open_v2(d_base.c_str(),&handle,SQLITE_OPEN_READWRITE ,NULL))
{
// does something.
}
I am trying to reach the qt resource folder without success. It works if I export into an other folder like C:\\Temp\\18_25_21_18_09_2014.svg, but it doesn't work if I use an URL like :/Temp/18_25_21_18_09_2014.svg.
Here is the code:
QString fileName(":/Temp/Temp" + QDateTime(QDateTime::currentDateTime()).toString("hh_mm_ss_dd_MM_yyyy") + ".svg");
QSvgGenerator generator;
generator.setFileName(fileName);
generator.setSize(this->size());
generator.setViewBox(QRect(QPoint(0,0), this->size()));
generator.setTitle(tr("bubble_svg"));
generator.setDescription(tr("bubble_svg"));
_painter.begin(&generator);
_painter.setRenderHint(QPainter::Antialiasing);
_painter.setRenderHint(QPainter::HighQualityAntialiasing);
this->render(&_painter);
_painter.end();
Also I created a prefix called Temp and a folder called Temp.
It looks like that also QDirIterator can reach the folder, only the QSvgGenerator couldn't.
QDirIterator it(":/Temp/Temp", QDir::Files, QDirIterator::Subdirectories);
while (it.hasNext()) {
qDebug() << "FILE FOUND " << it.next();
}
The result of this part of code:
FILE FOUND ":/Temp/Temp/18_35_19_18_09_2014.svg"
I appreciate every idea. Thanks for dropping by and taking time with the questions!
Ok, I understood and post it as answer.
Unfortunately it is impossible. Qt Resource System forbid this. As documentation said:
The Qt resource system is a platform-independent mechanism for storing binary files in the application's executable. It means that resources are read only, thuis files compiled into the executable, you can't write it because this files storing in your exe file. Especially an executable can’t modify itself while it is running. You’ll have to re-compile the QRC file (using RCC) and then re-build the EXE file, if one of the resources has changed.
As you can see, you should provide another way to storing and using your files.
I hope it was useful for you.