0

I need to get the path to the application dir or the executable.

I found that

QString appPath = QCoreApplication::applicationDirPath();

would be the way to do it.

But when I run, I get error:

QCoreApplication::applicationDirPath: Please instantiate the QCoreApplication object first

If i try to create an instance of QCoreApplication though i get build errors...

error: no matching function for call to 'QCoreApplication::QCoreApplication()'

Using QApplication instead of QCoreApplication gives me a similar error.

This call is not made from main() that instantiates an application type class... it is from a config class very far away.

How is this done ?

Qt 4.8

Note: what I am trying to get is the actual app directory (for mac, i will use it to generate an absolute path to Contents/Resources).

Using a relative path did not work (I got a funny @ symbol when I printed the path, before the relative path portion, and the file I tried to load from there failed to load)

@/myapplication.app/Contents/Resources/myfile

instead of

path/myapplication.app/Contents/Resources/myfile
TheDarkKnight
  • 27,181
  • 6
  • 55
  • 85
Thalia
  • 13,637
  • 22
  • 96
  • 190

1 Answers1

3

To access a file or item in the Resources folder, it would be possible to start with the executable's location and work from there. However, if Apple decide to change the format of the bundle, this may cause issues.

As Qt doesn't provide this directly, I suggest using Apple's Core Foundation, which can be used from within a Qt application. Let's assume we want a resource called "itemName", which resides in the Resources folder and we'll get its full path in the QString itemPath:-

   // get item path...
    QString itemPath;
    {
        CFURLRef appUrlRef;
        appUrlRef = CFBundleCopyResourceURL(CFBundleGetMainBundle(), CFSTR("itemName"), CFSTR("bundle"), NULL);

        CFStringRef macPath = CFURLCopyFileSystemPath(appUrlRef, kCFURLPOSIXPathStyle);
        itemPath = CFStringGetCStringPtr(macPath, CFStringGetSystemEncoding());

        // must release core foundation objects
        CFRelease(appUrlRef);
        CFRelease(macPath);
    }

In order to use the CoreFoundation functions, just add the include to your implmentation file: -

 #include <corefoundation/CFBundle.h>

And add the relevant framework in the project file (.pro)

LIBS += -framework CoreFoundation
TheDarkKnight
  • 27,181
  • 6
  • 55
  • 85
  • Sorry I forgot to mention, I am stuck to 4.x (using 4.8)... and I know the application can be anywhere, which is why I am trying to retrieve the location of the .app (so I can generate an absolute path inside, to Contents/Resources) – Thalia Nov 04 '14 at 16:34
  • I will try it on mac in a bit, quick question - CFBundleCopyResourceURL looks like items I have seen in the plist file - will I need to add anything there too ? – Thalia Nov 04 '14 at 16:52
  • I don't believe it's anything to do with this instance. The function merely returns the location of a named resource in the bundle, as described in Apple's documentation: https://developer.apple.com/library/Mac/documentation/CoreFoundation/Reference/CFBundleRef/index.html#//apple_ref/c/func/CFBundleCopyResourceURL – TheDarkKnight Nov 04 '14 at 16:54
  • I have looked through documentation of bundles a bit... but the code above gives me "Contents/Resources" which is the same relative path that I can just type... not absolute path. The resource requires absolute path to open. So whether I use the methods above, or manually type "Contents/Resources" in the path, I still need to know the app path. – Thalia Nov 04 '14 at 19:25
  • 1
    used this answer ... some of the info in your answer helped me get it to work http://stackoverflow.com/a/577143/1217150 – Thalia Nov 04 '14 at 21:01
  • I used CFURLCopyAbsoluteURL to get an absolute URL from the relative URL that CFBundleCopyResourceURL returns. – Tim Angus Oct 25 '17 at 13:19