相对路径(从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;
}

使用gcc编译后:

g++ abc.cpp -o abc

然后运行程序 abc,一切都很正常。但如果执行程序abc和dbzhang800.txt不在同一个目录下,此时程序将无法找到文件。

工作目录(Current Working Directory)

=相对路径,肯定绕不过工作目录(working directory),它有时也被称为当前工作目录,所有的相对路径都是从工作目录开始解释的。

一般来说,每个进程都有一个与之相关联的分级文件系统(hierarchical file system)下的目录,称之为该进程的当前工作目录。默认为程序启动的目录或者父进程启动此应用程序时所在的目录。
但是当前工作目录是可以通过程序进行设置:

ISO C标准

    #include <dir.h>

    int chdir(const char *path);  //设置工作目录
    char *getcwd(char *buf, int n); //读取工作目录

Qt中相关函数

    [static] bool QDir::setCurrent(const QString &path)
    [static] QString QDir::currentPath() 

程序所在目录

ISO C标准

    //获取当前程序所在路径
    char pszFileName[MAX_PATH] = { 0 };
    GetModuleFileName(NULL, pszFileName, MAX_PATH);

Qt中相关函数

    [static] QString QCoreApplication::applicationDirPath()

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

一个有用的函数

当我们在windows下使用Qt的时候,生成的可执行程序会在debug或release目录下,我们要访问的文件在 project.pro 文件所在目录(或其子目录)下。此时如何使用相对路径?

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

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

直接使用下发的方式肯定是无法同时兼容debug和release两种情况

QFile(doc/dbzhang800.txt)

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

QResource资源文件的路径

|-- project.pro
|-- images/
|     | -- landscape.png
|
|-- styles.qss
|
|-- resource.qrc
|
|-- main.cpp

resource.qrc 配置方式如下:

<RCC>
    <qresource prefix="/menu">
        <file>images/landscape.png</file>
    </qresource>
    <qresource prefix="/qss">
        <file>styles.qss</file>
    </qresource>
</RCC>

则可以分别如下使用:

QIcon icon(":/menu/images/landscape.png");
QFile f(":/qss/styles.qss");

以冒号:开头的路径始终被视为绝对路径,因为它们表示 QResource。
当然,如果在main.cpp中,通过QDir::setCurrent()将当前路径设置为project.pro对于目录;

QIcon icon("images/landscape.png");
QIcon icon("./images/landscape.png");
QFile f("styles.qss");
QFile f("./styles.qss");

shadow build

shadow build 就是将源码路径和构建路径分开(也就是生成的makefile文件和其他产物都不放到源码路径),以此来保证源码路径的清洁。
qt creator默认使用 shadow build构建项目
qt creator shadow build 设置

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

shadow build的实现

  1. Makefile out-of-source

qt creator实际采用如下类似方式将Makefile生成在指定的目录

cd ../build-vs2008
qmake ../project-sources/project.pro
make
  1. 中间产物的out-of-source
    通过在pro(pri.)文件中,增加如下配置,实现编译中间产物的out-of-source
环境变量含义
DESTDIR = $$PWD/bin目标文件放置位置
DLLDESTDIR = $$[QT_INSTALL_BINS]win下拷贝动态库到qt安装路径
MOC_DIR = $$PWD/tempmoc的产物放置何处
RCC_DIR = $$PWD/temprcc的产物放置何处
UI_DIR = $$PWD/tempuic的产物放置何处
OBJECTS_DIR = $$PWD/temp编译器生成的.o(.obj)等文件放置

pro文件中支持的变量

PWD使用该变量的文件(.pro 或 .pri)所在目录,注意对比下一个
_ PRO_FILE_PWD_pro文件所在目录(注意:即使它用在pri文件内,也是指代的包含它的pro文件所在的目录)
_ PRO_FILE_pro文件的全路径
OUT_PWD生成的makefile文件所在路径,和_PRO_FILE_PWD_对应

当不使用shadow build构建时,OUT_PWD 和 PRO_FILE_PWD 是相同的,据此,我们可以判断采用了何种构建方式,进而采用不同的动作:

!contains(_PRO_FILE_PWD_, $${OUT_PWD}) {
#do something when using shadow build
}
#直接使用equals更好一些,但是manual对此没有任何说明(所以我不清楚你的qmake对此是否支持,至少Qt4.5以后都是支持的)
!equals(_PRO_FILE_PWD_, OUT_PWD) {
#do something when using shadow build
}

采用out-of-source构建时,我们可能需要将一些文件从源码目录拷贝到构建目录下,用cmake时,这个很容易做到,但在qmake下,似乎缺少通用的方式,一个简单的demo如下:

FILES_COPY_SRC = $$SOURCES /
                 dbzhang800.txt /
                 images/abc.png /
                 i18n/abcd.qm

win32{
    COPY = copy /y
    MKDIR = mkdir
}else{
    COPY = cp
    MKDIR = mkdir -p
}
!equals(_PRO_FILE_PWD_, OUT_PWD) {
    for(f, FILES_COPY_SRC){
        dist_file = $$OUT_PWD/$$f
        dist = $$dirname(dist_file)
        win32:dist = $$replace(dist, /, \\)  	#windows下,必须先将路径分割符由“/”替换成 “/”
        !exists($$dist):system($$MKDIR $$dist) 	#目标目录不存在,创建目录
        !exists($$dist_file):system($$COPY $$f $$dist)	#目标文件不存在,拷贝文件
    }
}

本文参考下面链接整理:
原文链接:https://blog.csdn.net/dbzhang800/article/details/6343838
原文链接:https://blog.csdn.net/dbzhang800/article/details/6363165

  • 0
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值