Important: Please read the Qt Code of Conduct - https://forum.qt.io/topic/113070/qt-code-of-conduct

Create File on Mac with QStandartPath failed



  • Hey Guys I love QT amazing work!

    I'm having a problem. The program is not able to create any file on MAC (WIN is fine).
    I would prefer the file being created in the App directory or to write into a existing QRC file.
    If that is not possible on Mac creating the file in Documents is fine.

    My code:

    QFile lastLZK (QStandardPaths::DocumentsLocation+"/cfLZK.activated");
    lastLZK.open(QIODevice::WriteOnly | QIODevice::Text);
    QApplication::processEvents();
    QString passKey;
    passKey = ui->lineEdit->text();
    QTextStream getKey(&lastLZK);
    getKey << passKey;


    This code should work the syntax is right or isn't it?

    I hope u can provide me with a solution.

    Thanks in advance.


  • Lifetime Qt Champion

    Hi and welcome to the forums

    Try with
    StandardPaths::writableLocation(QStandardPaths::AppLocalDataLocation)

    Also the QApplication::processEvents(); is not needed at all and you should check
    the return value of open and use lastLZK.errorString(); to see what it says.



  • @mrjj said in Create File on Mac with QStandartPath failed:

    StandardPaths::writableLocation(QStandardPaths::AppLocalDataLocation)

    Thanks for that hint! -> (Also the QApplication::processEvents(); is not needed)

    For some reason it is working on QT engine.
    If I start the app after building and creating it with qmake it still does't work, can you tell me where I can find the file that should be created so I can check if it worked.
    I tried to clean all and recreating it but does not seem to have any effect.

    Thanks for that quick answer!


  • Lifetime Qt Champion

    Hi
    Just do
    qDebug() << "where:" << StandardPaths::writableLocation(QStandardPaths::AppLocalDataLocation);
    to see where it points. I have no mac so cant test :)

    Docs says
    "~/Library/Application Support/<APPNAME>", "/Library/Application Support/<APPNAME>". "<APPDIR>/../Resources"
    so you better check what u get :)



  • I checked and I got an error.

    New code:

    QFile lastLZK (QStandardPaths::AppLocalDataLocation+"/cfLZK.activated");
    lastLZK.open(QIODevice::WriteOnly | QIODevice::Text);

        if (!lastLZK.error())
        {
    
        QString passKey;
        passKey = ui->lineEdit->text();
        QTextStream getKey(&lastLZK);
        getKey << passKey;
    
        }else {
        ui->lineEdit->setText("error");
        }
    

    There was no folder or file created in:
    /Library/Application Support/


  • Lifetime Qt Champion



  • @aha_1980

    syntax won't work (invalid argument type 'QString' to unary expression)



  • Lifetime Qt Champion

    Hi
    Wait, you are using it wrong i think.
    QStandardPaths::AppLocalDataLocation is just an enum. not a string
    so you have to do
    QStandardPaths::writableLocation(QStandardPaths::AppLocalDataLocation);

    like

    QString FileName = QStandardPaths::writableLocation(QStandardPaths::AppLocalDataLocation) + "/cfLZK.activated";
        QFile lastLZK (FileName);
        if  (! lastLZK.open(QIODevice::WriteOnly | QIODevice::Text) ) {
            ui->lineEdit->setText("file open error:"  + FileName + " errorStr:" + lastLZK.errorString()  );
            return;
        }
    
        QString passKey;
        passKey = ui->lineEdit->text();
        QTextStream getKey(&lastLZK);
        getKey << passKey;
    


  • @mrjj said in Create File on Mac with QStandartPath failed:

    QStandardPaths::writableLocation(QStandardPaths::AppLocalDataLocation) + "/cfLZK.activated";

    0_1562421976423_Screen Shot 2019-07-06 at 16.05.41.png

    I tried that's what I get out of it.


  • Lifetime Qt Champion

    @CForce-IT_Admin
    well the syntax is slightly off, you try to assign string to QFile :)

    Use QString and give that to QFile.

    QString FileName = QStandardPaths::writableLocation(QStandardPaths::AppLocalDataLocation) + "/cfLZK.activated";
    QFile lastLZK (FileName);



  • @mrjj said in Create File on Mac with QStandartPath failed:

    if (! lastLZK.open(QIODevice::WriteOnly | QIODevice::Text) ) {
    ui->lineEdit->setText("file open error:" + FileName + " errorStr:" + lastLZK.errorString() );
    return

    Sorry I rushed :) din't saw u had a second instance 'Filename'

    output:

    file open error:/Users/blackbeard/Library/Application Support/CForce-IT/CForce-IT Secure Data Manager/cfLZK.activated errorStr:No such file or directory


    I might have to find a second solution. So I explain.

    I need to save or store what is written in ui->lineEdit->Text()
    and when the program starts to take the text and put back to ui->lineEdit->Text("stored text imput").


  • Lifetime Qt Champion

    Hi
    It says /Users/blackbeard/Library/Application Support/CForce-IT/CForce-IT Secure Data Manager/
    does not exists. is this true ?

    It can be as i had to make the folder myself on Windows but i have no idea how it works on Mac.



  • @mrjj
    yes it is true.

    I think it might be some missing permissions to write.

    I first tried to use QSettings but could't get the syntax to work. Maybe you could provide me with an example. I try to remember a QlineEdit input that I can bring back on program start. This should work Cross-Platform and would be the better solution.

    Thanks for your help.


  • Lifetime Qt Champion

    @CForce-IT_Admin
    Ok so its the same as on windows where the last folder of the location didn't exists for a new app.

    Well you can use it like this. ( very basic sample)

    void MainWindow::loadSettings()
    {
        QSettings settings("MyEditorName","myAppName");
        QString sText = settings.value("text", "").toString();
        ui->lineEdit->setText(sText);
    }
    
    void MainWindow::saveSettings()
    {
        QSettings settings("MyEditorName","myAppName");
        QString sText = ui->lineEdit->text();
        settings.setValue("text", sText);
    }
    


  • I'm experienced similar issues on Mac !
    I can't access to the writable location from the app contructor, i move all the code to exec() and here it works:

    int WebApp::exec()
    {
        setupFromPrefs();       // les valeurs sont fausses si appelé dans le constructeur !!!
    //  Impossible d'accéder aux fichiers du dossier 'writable location' dans le constructeur !
        sHistoryManager=new HistoryManager(0);
    

    The comments in French say:

    • The values return by QSettings are wrong
    • no access to files in the writable location ( no error, the length of the file is zero)

    I'm reading a file in the contructor of HistoryManager like that:

    HistoryManager::HistoryManager(QObject* parent) : QObject(parent)
    {
        QString path=QStandardPaths::writableLocation(QStandardPaths::AppDataLocation);
    path+=HistoryFile;
    
    QFile hFile(path);
    
    if(hFile.exists())
    	loadHistory(hFile);
    
    	createDialog();
    
    	EventCenter::instance()->addObserver(Event_AppPrefsDidChange,this);
    }
    

    loadHistory reads zero bytes if processed to early in the startup Qt app sequence, move the code in exec() function solves the issue for me.

    I have to mention that this kind of "synchronizing" issues are not unique to Qt, I see that on Mac too.
    Even in your own code, there's a lot of circonstances where you need to pass in the eventloop before proceding forward.
    That's why I have a simple macro for that:

    #define InvokeLater(slot)  QMetaObject::invokeMethod(this, #slot,Qt::QueuedConnection)
    

    So, if you experienced strange issues as discribe here in the early state of your app, try to postpone the process, it may worth a try ;)


  • Lifetime Qt Champion

    Hi,

    Might be a silly question but did you check that the folder actually exists ?

    The path is correct in the sense that it is where you should write but it might not exists yet.

    So check the path returned, if the folder doesn't exist, create it first and then create your file in it.



  • Thank u so much! Works like a charm.

    I had to adjust it a bit but works great here the code:

    void Encrypt::loadSettings()
    {
    QSettings settings("CForce_SDM","passKey");
    QString getkey = settings.value("text", "").toString();
    ui->lineEdit->setText(getkey);
    }

    void Encrypt::saveSettings()
    {
    QSettings settings("CForce_SDM","passKey");
    QString passKey = ui->lineEdit->text();
    //to clear key
    //QString passKey = "";
    settings.setValue("text", passKey);
    }


    This was exactly what I was looking for great job @mrjj


  • Lifetime Qt Champion

    @CForce-IT_Admin

    //to clear key
    //QString passKey = "";

    No! An empty QString is just: QString passKey;


Log in to reply