0

Would really appreciate your help. I'm new to Qt and C++.

I managed to get this working previously, but for some reason am no longer able to do so. I haven't touched anything to do with the writing of files, but all functions pertaining to file writing no longer seem to function. Here's an example of one of the simpler write functions:

#include <QStringList>
#include <QDir>
#include <QFile>
#include <QString>
#include <QTextStream>


void HandleCSV::writeToPIDCSV(UserAccount newUser)
{
    // Storing in userPID db
    QString filePath = returnCSVFilePath("dbPID");
    qDebug() << "File path passsed to writeToPIDCSV is " <<  filePath;

    // Open CSV filepath retrieved from associated dbName
    QFile file(filePath);
    if (!file.open(QIODevice::ReadWrite | QIODevice::Append))
    {

        qDebug() << file.isOpen() << "error " << file.errorString();
        qDebug() << "File exists? " << file.exists();
        qDebug() << "Error message: " << file.error();
        qDebug() << "Permissions err: " << file.PermissionsError;
        qDebug() << "Read error: " << file.ReadError;
        qDebug() << "Permissions before: " << file.permissions();
        // I tried setting permissions in case that was the issue, but there was no change
        file.setPermissions(QFile::WriteOther);
        qDebug() << "Permissions after: " << file.permissions();


    }
//    if (file.open(QIODevice::ReadWrite | QIODevice::Append))

    else
    {
        qDebug() << "Is the file open?" << file.isOpen();

        // Streaming info back into db
        QTextStream stream(&file);
        stream << newUser.getUID() << "," << newUser.getEmail() << "," << newUser.getPassword() << "\n";

    }
    file.close();
}

This gets me the following output when run:

File path passsed to writeToPIDCSV is  ":/database/dummyPID.csv"
false error  "Unknown error"
File exists?  true
Error message:  5
Permissions err:  13
Read error: 1
Permissions before:  QFlags(0x4|0x40|0x400|0x4000)
Permissions after:  QFlags(0x4|0x40|0x400|0x4000)

The file clearly exists and is recognised when run, but for some reason file.isOpen() is false, and the permissions show that the user only has read (not write) permissions that are unaffected by permission settings.

Would someone have a clue as to why this is happening?

Many thanks in advance

Update

Thanks @chehrlic and @drescherjm - I didn't realise that I can only read but not write to my resource file!

Using QStandardPaths allows me to write to my AppDataLocation. I've included the code below for others who might encounter similar issues, adapted from https://stackoverflow.com/a/32535544/9312019

#include <QStringList>
#include <QDir>
#include <QFile>
#include <QString>
#include <QTextStream>
#include <QStandardPaths>

void HandleCSV::writeToPIDCSV(UserAccount newUser)
{
    auto path = QStandardPaths::writableLocation(QStandardPaths::AppDataLocation);
    if (path.isEmpty()) qFatal("Cannot determine settings storage location");
    QDir d{path};
    QString filepath = returnCSVFilePath("dbPID");

    if (d.mkpath(d.absolutePath()) && QDir::setCurrent(d.absolutePath()))
    {
        qDebug() << "settings in" << QDir::currentPath();
        QFile f{filepath};
        if (f.open(QIODevice::ReadWrite | QIODevice::Append))
        {
            QTextStream stream(&f);
            stream << newUser.getUserFirstName() << ","
                   << newUser.getUserIDNumber()  << "\n";
        }
    }
}

Am now testing to make this work with my Read functions.

If there's any way to be able to write to the Qt program's folder (or build folder), I'd really appreciate it!

Chris
  • 3
  • 2
  • 1
    `:/database/dummyPID.csv` is that a resource file? You can read but can not modify resources that are in your executable. If that was not intended to be a resource file its not a valid windows file name. – drescherjm Jun 21 '22 at 14:01
  • Is it possible that the function `returnCSVFilePath` open the file and doesn't close it? – Marco Beninca Jun 21 '22 at 14:16
  • From Qt documentation error 5 is **The file could not be opened.** [documentation](https://doc.qt.io/qt-5/qfiledevice.html#FileError-enum) – Marco Beninca Jun 21 '22 at 14:19
  • Thanks @drescherjm, yes it's a resource file. It didn't work when it wasn't pulled in as a resource file. How would I be able to modify files in my application directory? – Chris Jun 21 '22 at 23:28
  • ***How would I be able to modify files in my application directory?*** On windows it should be protected by UAC so you should not attempt to write to `c:\Program Files\myappname` On linux normal users should not have write permissions on the bin folder of your OS. – drescherjm Jun 21 '22 at 23:37
  • @drescherjm hmm, maybe application directory isn't the right term. Apologies in advance - I'm new to programming and don't always have the right terminology. My Qt program folder currently includes my build folder and app folder with i.e. my resource and CMakeLists.txt files. Is there any way to create files in that folder so that I'm able to zip and send the entire application to another person without sending test files separately? Or does this violate UAC? – Chris Jun 21 '22 at 23:51
  • ***Or does this violate UAC?*** No, you can write files in the build folder. – drescherjm Jun 21 '22 at 23:59
  • @drescherjm I'm trying to use documentation from https://doc.qt.io/qt-5/qstandardpaths.html#details to figure out how to write to the build folder, but can't seem to find a way to do that :( I'm still not very good at reading the docs and translating it to actual working code. Would you have any idea how to set the path to write to the build folder? – Chris Jun 22 '22 at 00:15

1 Answers1

1

You can not write to a Qt resource. If you want to update/write to a file you should put the file into a writeable filesystem. To e.g. place it in the appdata folder you can use QStandardPaths::writeableLocation(QStandardPaths::ApplicationsLocation)

chehrlic
  • 913
  • 1
  • 5
  • 5
  • Thanks @chehrlic! I didn't realise that i wouldn't be able to do that. I tried QStandardPaths and am now able to write to a file in ../AppData/Roaming/[AppName]. I'll include the code in OP for other people coming to look for a similar solution. Is there any way to write to my application's directory or build folder? To give some context, I'm new to SwD in general. This is a school project where we need to share (and eventually submit) our Qt folder, preferably including test data. Writing in the AppData folder means submitting and "installing" test data separately, which isn't preferred. – Chris Jun 21 '22 at 23:43
  • Writing to the folder where your application is will not work when the application is installed e.g in C:\Program Files\ since a normal user has no write access to those folders. But for testing you can use [QCoreApplication::applicationDirPath()](https://doc.qt.io/qt-5/qcoreapplication.html#applicationDirPath) – chehrlic Jun 22 '22 at 15:43