QFile无法打开包含Unicode字符的文件名

3 投票
1 回答
1456 浏览
提问于 2025-04-17 15:27

我在使用PySide的时候遇到了一个问题。我在处理一些图片,使用了QtCore.QImage,发现那些路径中有Unicode字符的图片文件打不开。
于是我开始调查,发现QFile也有同样的问题。

我尝试给它传入一个'utf8'编码的字节串,还有一个解码后的Unicode字符串,结果都是一样的。
我还试过使用QFile.encodeNameQFile.decodeName这两个函数,但它们只是把文件名中的非ASCII字符去掉了。

我写了一个脚本来演示这个问题:

#!/usr/bin/env python
# -*- coding: utf-8 -*-

import os

from PySide.QtCore import QFile, QIODevice

try:
    os.makedirs(u'/tmp/qttest')
except:
    pass #probably dir just exists
os.chdir(u'/tmp/qttest')

def make_file(fn):
    f = open(fn, 'w')
    f.close()

def check_file(fn):
    f = QFile(fn)
    f.open(QIODevice.ReadOnly)
    return f.isReadable()    

fna = u'somefile.txt'
fnu = u'einhverskrá.txt'

make_file(fna)
make_file(fnu)

print fna+u' was opened successfully: ', check_file(fna)
print fnu+u' was opened successfully: ', check_file(fnu)

print fna+u' exists: ', os.path.exists(fna)
print fnu+u' exists: ', os.path.exists(fnu)

输出结果

somefile.txt was opened successfully:  True
einhverskrá.txt was opened successfully:  False
somefile.txt exists:  True
einhverskrá.txt exists:  True

有人能解释一下这个问题吗?

更新
在查看源代码后,我发现QFile.open()在Unix系统上总是会通过这个函数处理文件名:

static QString locale_decode(const QByteArray &f)
{
#if defined(Q_OS_DARWIN)
    // Mac always gives us UTF-8 and decomposed, we want that composed...
    return QString::fromUtf8(f).normalized(QString::NormalizationForm_C);
#elif defined(Q_OS_SYMBIAN)
    return QString::fromUtf8(f);
#else
    return QString::fromLocal8Bit(f);
#endif
}

这总是导致字符串中的Unicode字符被去掉。

1 个回答

2

是的,我觉得我找到了自己问题的解决办法。

from PySide.QtCore import QTextCodec
QTextCodec.setCodecForLocale(QTextCodec.codecForName('UTF-8'))

在那之后,Unicode 文件名似乎能够正常处理了。

不过,我还得看看这个修复是否会对其他平台产生不好的影响。

撰写回答