QT 路径问题

本文转自

http://blog.youkuaiyun.com/dbzhang800/article/details/6363165

很实用的文章


在Qt论坛经常看到网友抱怨:

  • QPixmap("dbzhang800.png") 加载图片不成功
  • QFile("dbzhang800.txt") 打开文件失败
  • ...

遇到这种问题,我一般回答:请注意区分进程的"工作目录 "与程序所在的目录 。但这种回答似乎还是显得太苍白了,既然如此,整理一下吧。

  • 用到了相对路径,你清楚"相对"是相对那个目录的么?
  • 当你抱怨Qt时,你知道它与Qt无关么?
Qt 是 C++ 的库,我们还是从C++开始看吧(注:你可能会对  用ISO C++实现自己的信号槽(另类的Qt学习)  以及  从 C++ 到 Qt  感兴趣) 。

相对路径

刚接触文件操作时,我们应该都写过这种简单的小程序吧:

#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;
}

我们在可执行文件的同级目录下放置dbzhang800.txt文件,然后调用编译器编译程序

cl abc.cpp

g++ abc.cpp -o abc

然后运行程序 abc,一切都很正常,是不?

可能是这个原因吧,导致很多人误认为 :相对目录相对的就是应用程序所在的目录!

你有没有没试过:

|-- dir1/
|    |-- abc(.exe)
|    `-- dbzhang800.txt
|
`-- dir2/

如果你在终端(或cmd窗口)中切换目录到 dir2,然后通过 ../dir1/abc 运行程序,你的程序还能找到文本文件么?

如果你想让它找到,此时文件应该放置到哪个目录?

工作目录

遇到相对路径,我们肯定绕不过工作目录(working directory)。它有时也被称为当前工作目录(c urrent  w orkingd irectory),所有的相对路径都是从工作目录开始解释的。 我们可以通过_chdir 等函数来更改进程的工作目录。

接前面的例子,如果你真的对工作目录没有感觉,不妨直接输出来自己看看(网络上你可能会看到其他posix等提供的函数,我们只使用ISO C++标准中的函数):

#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);
   }
}
  • 我们调用 _getcwd 来获得当前的工作目录
  • 你可以在终端或cmd中切换到其他目录,通过绝对路径来调用你的这个程序,来观察输出
  • 如果你在linux下,你可以创建启动器,然后启动器中可以设置工作目录
  • 如果你在windows下,你可以为其创建快捷方式,快捷方式属性中可以设置/修改工作目录

进程内修改工作目录

看个无聊的例子:

#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;
}
  • 使用  _chdir   修改工作目录

  • 现在,程序将去打开C盘temp目录下的文本文件

注:_chdir   和  _getcwd 都有对应的宽字符(wchar_t)版本,此处不涉及(如果你要使用宽字符,不妨先考虑看看此文C 源文件内的中文(2) )。

回到Qt

Qt 是C++的库,所以上面的东西你完全可以直接用。不过由于Qt提供更好用的东西QDir,我想你应该不会想着在Qt中使用前面提到的C、C++的中函数。

注意:如果你要操作的文件是只读的,而且程序编译完成后这些文件不需要变化,那么请首先考虑采用Qt的资源文件.qrc(本文不涉及这部分)。

下面:我们不妨看看前两个函数在Qt中的等价物。

获得工作目录

如果你对工作目录依然不熟悉,使用相对路径出现问题时,请首先考虑使用下列语句:

qDebug()<<QDir::currentPath();

看看和你预想的是否相符。

修改工作目录

  • 你很少需要这个操作
  • 如果你用到了,请注意
bool QDir::setCurrent ( const QString & path ) [static]
  • 而不是
bool QDir::cd ( const QString & dirName )
bool QDir::cdUp ()
void QDir::setPath ( const QString & path )

程序所在目录

如何知道你程序自己在那个目录下,这是一个和平台相关的问题(ISO C、C++ 目前似乎还不能告诉我们答案)。幸好Qt提供了很好的封装了:

QString QCoreApplication::applicationDirPath () [static]

如果你想使用相对路径访问和可执行程序的同目录下的文件,你可以将工作目录设置成该目录!

或者(这应该是更好点的方法),用该目录和你的相对路径先直接组合成绝对路径再使用。

可是 ,你有没有这个问题:当我们在windows下使用Qt的时候,生成的可执行程序会在debug或release目录下,我们要访问的文件在 project.pro 文件所在目录(或其子目录)下。这可怎么办是好?

一个有用的函数

如果你想访问工程目录下的doc/dbzhang800.txt文件:

|-- project.pro
|-- doc/
|     `-- dbzhang800.txt
|
|-- release/
|     `-- abc.exe
|
`-- debug/
      `-- abc.exe

直接

QFile(doc/dbzhang800.txt);

好用么?如果在QtCreator 等环境下运行,一般可以工作,可是,进到debug下双击,却不工作了(不要告诉我你看了上面内容还不知道原因哈)。

问题的解决方案来自C++ GUI Qt4 编程一书,我相信你肯定见过这个函数:

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;
}

这个函数怎么用?   我们只需要:

QFile(directoryOf("doc").absoluteFilePath(dbzhang800.txt));

shadow build

qmake 很早就提供shadow build功能,但也就QtCreator默认使用了该功能以后,大部分人才开始注意到它。

|-- project-sources/
|       |-- project.pro
|       `-- main.cpp
|
|-- build-vs2008/
|       |-- Debug/
|       |    `-- main.exe
|       `-- Release/
|            `-- main.exe 
|-- build-vs2005/
|-- build-mingw/
|-- build-symbian/
|-- build-dbzhang800/
|-- ...

这儿没有神奇之处,只不过一般资料上介绍qmake都是这样说的:

qmake project.pro
make

而 qtcreator 是这么做的

cd ../build-vs2008
qmake ../project-sources/project.pro
make

这种情况下,我们一般需要将一些文件拷贝到构建目录下,具体可参考  浅谈 qmake 之 shadow build   最后给的一段代码

### 关于Qt路径配置与环境变量 在开发过程中,正确配置Qt路径和环境变量对于项目的正常编译和运行至关重要。以下是关于Qt路径配置和环境变量的相关说明: #### 1. **Windows平台下的Qt路径配置** 在Windows平台上,通常需要将Qt安装目录中的`bin`子目录添加到系统的`PATH`环境变量中。这样可以确保命令行能够识别并执行Qt相关的可执行文件和工具[^3]。 例如,如果Qt安装在`C:\Qt\5.15.2\msvc2019_64`,则应将以下路径添加到`PATH`环境变量中: ```plaintext C:\Qt\5.15.2\msvc2019_64\bin ``` 此操作可以通过系统属性对话框完成,或者通过PowerShell脚本实现自动化配置。 --- #### 2. **Linux/Mac平台下的Qt路径配置** 在Linux或Mac OS X环境下,同样需要将Qt的`bin`目录添加到用户的`PATH`环境中。此外,还需要考虑动态链接库的加载路径,即设置`LD_LIBRARY_PATH`(Linux)或`DYLD_LIBRARY_PATH`(macOS)。这些变量用于告知操作系统在哪里寻找共享库文件[^2]。 假设Qt安装在`/opt/qt/5.15.2/gcc_64`,那么可以在`.bashrc`或`.zshrc`中添加如下内容: ```bash export PATH=/opt/qt/5.15.2/gcc_64/bin:$PATH export LD_LIBRARY_PATH=/opt/qt/5.15.2/gcc_64/lib:$LD_LIBRARY_PATH ``` 完成后,需重新加载shell配置文件以使更改生效: ```bash source ~/.bashrc ``` --- #### 3. **Pro文件中的路径配置** 除了系统级的环境变量外,还可以在Qt项目文件(`.pro`)中定义特定的路径变量。常见的用法包括引入外部库、头文件夹以及其他资源文件的位置[^1]。 示例代码片段展示如何在`.pro`文件中指定自定义路径: ```makefile INCLUDEPATH += /path/to/include/files LIBS += -L/path/to/library/files -lmylib ``` 上述语句分别指定了头文件的搜索路径和链接器所需的库文件位置。 --- #### 4. **常见错误及其解决方案** 当遇到诸如“无法定位程序输入点_ZN10QArrayData10deallocateEPs_jj”的错误时,通常是由于缺少必要的依赖项或路径未正确定义所致。此时建议按照以下方法排查问题: - 确认目标机器上的Qt版本与开发者使用的版本一致; - 验证所有必需的DLL/SO文件均已随应用程序一同部署; - 使用工具如Dependency Walker (Windows) 或 `ldd` 命令(Linux),分析是否存在缺失的依赖关系。 --- #### 总结 无论是Windows还是Unix-like系统,合理地管理Qt相关路径及环境变量都是保障应用顺利构建的关键环节之一。务必依据实际需求调整相应参数,并注意跨平台间的差异性处理方式。
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值