为什么在Qt中,一个目录字符串去掉“/”后会返回其父目录qdir

5

可能是一个bug。请阅读webclectic的回答。

如果QFileInfo(filename)缺少'/',QDir::absolutePath会返回父级字符串。就像下面的代码一样。

QFileInfo file("e:/QtExample/mytest/out/res/res1/");
QFileInfo file_no("e:/QtExample/mytest/out/res/res1");

QDir dirFile = file.absoluteDir();
QDir dirFile_no = file_no.absoluteDir();

QString strDirFile = dirFile.absolutePath(); //"E:/QtExample/mytest/out/res/res1
QString strDirFile_no = dirFile_no.absolutePath(); //"E:/QtExample/mytest/out/res

我在我的QTreeView中找到了它。我的代码将从QTreeView::clicked信号调用该槽。
connect(ui.m_pView,SIGNAL(clicked(QModelIndex)),this,SLOT(myClicked(QModelIndex)));

该插槽将获取QModelIndex,然后使用QFileSystemMode::fileInfo获取QFileInfo信息。
QFileInfo rFileInfo = m_model.fileInfo(index);
QDir absDir = rFileInfoDir.absoluteDir();    

但是QFileInfo的返回值总是返回"e:/QtExample/mytest/out/res/res",所以如果我调用QFileInfo::absoluteDir获取目录,该目录是"res1"的父目录。因此,我将从期望目录中获取错误的entrylst。

我应该在absoluteFilePath()后面添加'/'来获取正确的QDir吗?

为什么strDirPath等于"E:/QtExample/mytest/out/res/res1",但rDir会列出"res"目录的entrylist?

//rFileInfoDir == E:/QtExample/mytest/out/res/res1
QString strDirPath = rFileInfoDir.absoluteFilePath();
QDir rDir = rFileInfoDir.absoluteDir();
3个回答

2

如果你深入了解 absoluteDir() 函数调用,你会明白为什么会出现这种情况。在Windows中,会调用qfsfileengine_win.cpp中的fileName函数。在这个函数中,有以下代码:

if (file == AbsolutePathName) {
        int slash = ret.lastIndexOf(QLatin1Char('/'));
        if (slash < 0)
            return ret;
        else if (ret.at(0) != QLatin1Char('/') && slash == 2)
            return ret.left(3);      // include the slash
        else
            return ret.left(slash > 0 ? slash : 1);
}

您可以看到它返回了最后一个分隔符左边的字符串部分。我不知道这是否是期望的行为还是一个错误。也许您可以为此发出一个Qt错误报告。文档对此问题没有明确说明。


很棒!!!你说得对!!! 我追踪了代码,并发现问题代码和你所写的一样。 Qt使用错误的Qstring来构造了一个错误的QDir! 谢谢您! 你先发现了这个bug,你自己会发布它吗? - Kaleidos
我不知道为什么Qt开发人员使用Qstring.left来截取右侧路径。使用错误的QString路径返回空QDir是否是一个好的解决方案? - Kaleidos
1
我刚刚追踪了代码,你找到了错误,所以请随意发布错误报告 :) 解决方案非常简单。它应该检查提供的字符串是否为目录。如果是,则返回它,否则返回最后一个分隔符左侧的字符串。 - pnezis

1

来自QFileInfo::absoluteDir()文档:

返回文件的绝对路径作为QDir对象。

在"/foo/bar"的情况下,文件是"bar",其目录是/foo。无论bar是目录还是普通文件,因为目录也是文件。如果您想要像“对于文件,返回父目录,对于目录,返回目录本身”这样的东西,您将不得不编写自己的小函数,通过QFileInfo::isDir进行测试以确定返回什么。


也许我没有理解你的意思。但是,正如你所看到的,这两个QDir :: absolutePath是不同的。QFileInfo file(“e:/QtExample/mytest/out/res/res1/”); QFileInfo file_no(“e:/QtExample/mytest/out/res/res1”); QString strDirFile1 = file.absoluteDir()。absolutePath(); QString strDirFile_no1 = file_no.absoluteDir()。absolutePath();因此,如果我使用第一个QDir,将得到正确的文件列表,但另一个则会出错。 - Kaleidos

0

e:/QtExample/mytest/out/res/res1/res 是指名为“res”的目录路径,e:/QtExample/mytest/out/res/res1/ 是指一个空目录的路径(称为“”)。因此,是否应该添加斜杠取决于您要做什么。

在我个人看来,最好不要添加末尾的斜杠,因为如果需要,可以很容易地添加它,而删除它则不那么直接。


谢谢您的回答。所以,如果我想要获取正确的QDir对象,我应该添加斜杠... - Kaleidos

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接