Qt Linguist 和 pylupdate4:.ts 文件中相对路径的基础是什么?

Qt Linguist and pylupdate4: which base for relative paths in .ts files?

编辑 2015 年 3 月 3 日

此问题应在 PyQt4 和 PyQt5 的下一个 PyQt 版本中修复:

http://www.riverbankcomputing.com/pipermail/pyqt/2015-April/035772.html

问题

pylupdate4 采用项目文件 (.pro),其中文件路径是相对于 .pro 文件本身的。

解析代码时,pylupdate4 将路径复制到 .ts 文件。

当 Qt Linguist 读取 .ts 文件时,它会考虑相对于 .ts 文件而不是 .pro 文件的路径。因此,在翻译时找不到源文件,无法显示代码。

如何让 Qt Linguist 显示源代码?

我可以将 .pro 文件与 .ts 文件放在 ts/ 目录中,但这看起来是一个遗憾的解决方法。这就是它的本意吗?

考虑到 Qt Linguist 的行为,不应该 pylupdate4.ts 文件中写入相对于 .ts 文件本身的路径,而不是 .pro 文件 ?

详情

我的 PyQt 项目结构如下:

src/
    my_software.py
    my_software.pro
    my_software/
        module_1.py
        module_2.py
            submodule_1/
                submodule_1_module_1.py
                submodule_1_module_2.py
    resources/
        ui/
            module_1.ui
            module_2.ui
            submodule_1/
                submodule_1_module_1.ui
                submodule_1_module_2.ui
    i18n/
        ts/
            my_software_fr.ts
            my_software_fr.qm
tools/
    tool_1.py

项目文件 (my_software.pro) 如下所示:

FORMS = resources/ui/module_1.ui resources/ui/module_2.ui resources/ui/submodule_1_module_1.ui resources/ui/submodule_1_module_2.ui
SOURCES = my_software/module_1.py my_software/module_2.py resources/ui/submodule_1_module_1.py resources/ui/submodule_1_module_2.py
TRANSLATIONS = i18n/ts/my_software_fr.ts

Qt Linguist 搜索例如

中的文件
/absolute/path/to/project/src/i18n/ts/my_software/module_1.py

而不是

/absolute/path/to/project/src/my_software/module_1.py

.ts (my_software_fr.ts) 文件看起来像

<?xml version="1.0" encoding="utf-8"?>
<!DOCTYPE TS>
<TS version="2.0" language="fr_FR">
<context>
    <name>Class</name>
    <message>
        <location filename="my_software/module_1.py" line="134"/>
        <source>Source text</source>
        <translation>Translated text</translation>

Qt 语言学家版本 4.8.6

pylupdate4 版本 4.8.6

编辑

source code of PyQt v4.11.3,文件metatranslator.cpp,l.470-471中,文件路径应该是相对于.ts文件写的:

QDir tsPath = QFileInfo(filename).absoluteDir(); 
QString fn = tsPath.relativeFilePath(msg.fileName()).replace('\','/');
t << " <location filename=\"" << fn << "\" line=\"" << msg.lineNumber() << "\"/>\n";

但是 relativeFilePath() 需要绝对路径。当给定一个相对路径时,它 returns 一个相对路径。在我的例子中,msg.fileName() 是我在 .pro 文件中输入的相对路径。

我可以修补 pylupdate 来解决这个问题:

--- metatranslator.cpp.bak      2015-03-12 10:39:18.984232622 +0100
+++ metatranslator.cpp  2015-03-12 10:37:36.225524474 +0100
@@ -471,8 +471,10 @@
             t << ">\n";
             if (!msg.fileName().isEmpty() && msg.lineNumber() >= 0) {
                 QDir tsPath = QFileInfo(filename).absoluteDir();
-                QString fn = tsPath.relativeFilePath(msg.fileName()).replace('\','/');
-                t << " <location filename=\"" << fn << "\" line=\"" << msg.lineNumber() << "\"/>\n";
+                QDir curdir = QDir(".");
+                curdir.makeAbsolute();
+                QString fn = tsPath.relativeFilePath(curdir.filePath(msg.fileName())).replace('\','/');
+                t << "        <location filename=\"" << fn << "\" line=\"" << msg.lineNumber() << "\"/>\n";
             }
             t  << "        <source>" << evilBytes( msg.sourceText(),
                                                   msg.utf8() )

或者 .pro 文件是否应该包含绝对路径?!

您问题的答案应该 删除pro 文件并从命令行执行所有操作(或者,更好的是,通过生成文件)。

但是,Qt 的 lupdate 工具提供了几个重要的选项,pylupdate(最重要的是 -locations-codecfortr)不可用。

如果没有这些,似乎唯一明智的做法是将所有翻译文件放在一个目录中,并确保所有相关路径都相对于它被引用。对我来说,这看起来是一个完全可以接受的解决方案,因为 pyqt 项目的任何其他部分都不应该关心 pro 文件(与 C++ 项目不同)。