Users often complain in the QT Forum:
- Qpixmap ("dbzhang800.png") fails to load the image
- Qfile ("dbzhang800.txt") failed to open the file
- ...
In this case, I generally answer: Please note that the process is differentiated"Working directory
"AndDirectory of the program
. But the answer seems too pale. In this case, sort it out.
- When the relative path is used, do you know that "relative" is relative to that directory?
- When you complain about QT, do you know it has nothing to do with QT?
QT is a C ++ library. Let's start with C ++ (Note: You may use Iso c ++ to implement your own signal slot (Alternative QT learning)
And from C ++ to QT
Interested)
.
Relative Path
We should have written such simple mini programs when we first came into contact with file operations:
#include <stdio.h>int main(){ FILE * pFile = fopen ("dbzhang800.txt" , "r"); if (pFile == NULL) { perror ("Error opening file"); } else { //do something fclose (pFile); } return 0;}
We place the dbzhang800.txt file in the directory of the executable file, and then call the compiler to compile the program.
cl abc.cpp
Or
g++ abc.cpp -o abc
Then run the program ABC. Everything is normal, right?
This may be the reason.Many mistakenly believe that
: The relative directory is the directory where the application is located!
Have you ever tried:
|-- dir1/| |-- abc(.exe)| `-- dbzhang800.txt|`-- dir2/
If you switch the directory to dir2 in the terminal (or cmd window) and run the program through ../dir1/ABC, can your program still find the text file?
If you want it to find out, which directory should the file be placed in?
Working directory
When we encounter a relative path, we certainly cannot bypass the working directory ). It is also called the current working directory (C
Urrent
W
OrkingD
Irectory ),All relative paths are explained from the working directory.
We can use_ Chdir
To change the working directory of the process.
In the previous example, if you really don't feel like a working directory, you may want to output it directly (on the network, you may see other functions provided by POSIX, etc, we only use functions in the iso c ++ standard ):
#include <direct.h>#include <stdlib.h>#include <stdio.h>int main( void ){ char* buffer; if( (buffer = _getcwd( NULL, 0 )) == NULL ) { perror( "_getcwd error" ); } else { printf( "Current Dir: %s /n", buffer); free(buffer); }}
- We call _ getcwd to obtain the current working directory.
- You can switch to another directory in the terminal or CMD and call your program through the absolute path to observe the output
- If you are running Linux, you can create a starter and set the working directory in the starter.
- If you are in Windows, you can create a shortcut for it. You can set/modify the working directory in the shortcut properties.
Modify the working directory in the process
Let's look at a boring example:
#include <stdio.h>#include <direct.h>int main(){ _chdir("c://temp"); FILE * pFile = fopen ("dbzhang800.txt" , "r"); if (pFile == NULL) { perror ("Error opening file"); } else { //do something fclose (pFile); } return 0;}
Use
_ Chdir
Modify working directory
- Now, the program will open the text file under the temp directory of drive C
Note:_ Chdir
And
_ Getcwd
All have the corresponding wchar_t version, which is not involved here (if you want to use a wide character, consider taking a look at the Chinese characters in the C source file in this article (2)
).
Back to QT
QT is a C ++ library, so you can use the above content directly. However, because QT provides better qdir, I think you should not think about using the C and C ++ functions mentioned above in QT.
Note: If the files to be operated are read-only and do not need to be changed after the program compilation is complete, you should first consider using the QT resource file. qrc (this part is not involved in this article ).
Next: Let's take a look at the equivalents of the first two functions in QT.
Get working directory
If you are still not familiar with the working directory, consider using the following statements when using the relative path:
qDebug()<<QDir::currentPath();
Check whether it matches your expectation.
Modify working directory
- You seldom need this operation
- Note that
bool QDir::setCurrent ( const QString & path ) [static]
bool QDir::cd ( const QString & dirName )bool QDir::cdUp ()void QDir::setPath ( const QString & path )
Program directory
How do you know that your program is in that directory? This is a platform-related question (iso c, C ++ does not seem to be able to tell us the answer yet ). Fortunately, QT provides a good encapsulation:
QString QCoreApplication::applicationDirPath () [static]
If you want to use a relative path to access files in the same directory as the executable program, you can set the working directory to this directory!
Or (this should be a better method), use the directory and your relative path to directly combine it into an absolute path before use.
However
Are you sure you want to solve this problem: when we use Qt in windows, the generated executable program will be in the debug or release directory, and the file we want to access will be in the project. under the directory (or its subdirectory) where the pro file is located. What should I do?
A useful function
If you want to access the DOC/dbzhang800.txt file under the project directory:
|-- project.pro|-- doc/| `-- dbzhang800.txt||-- release/| `-- abc.exe|`-- debug/ `-- abc.exe
Direct
QFile(doc/dbzhang800.txt);
Is it easy to use? If you are running in qtcreator or other environments, You can generally work. However, you can double-click under debug, but it does not work. (do not tell me why you have read the above content ).
The solution to the problem comes from the C ++ GUI qt4 programming book. I believe you have seen this function:
QDir directoryOf(const QString &subdir){ QDir dir(QApplication::applicationDirPath());#if defined(Q_OS_WIN) if (dir.dirName().toLower() == "debug" || dir.dirName().toLower() == "release" || dir.dirName().toLower() == "bin") dir.cdUp();#elif defined(Q_OS_MAC) if (dir.dirName() == "MacOS") { dir.cdUp(); dir.cdUp(); dir.cdUp(); }#endif dir.cd(subdir); return dir;}
How to use this function?
We only need:
QFile(directoryOf("doc").absoluteFilePath(dbzhang800.txt));
Shadow build
Qmake has long provided the shadow build function, but after qtcreator uses this function by default, most people will notice it.
|-- project-sources/| |-- project.pro| `-- main.cpp||-- build-vs2008/| |-- Debug/| | `-- main.exe| `-- Release/| `-- main.exe |-- build-vs2005/|-- build-mingw/|-- build-symbian/|-- build-dbzhang800/|-- ...
There is no magic here, But qmake is generally described as follows:
qmake project.promake
And qtcreator does this.
cd ../build-vs2008qmake ../project-sources/project.promake
In this case, we usually need to copy some files to the build directory. For details, refer
Shadow build of qmake
The last piece of code