Qt 资源系统与国际化
Qt 资源系统 (.qrc)
把图片、图标、QSS、配置文件编译进可执行文件。
<!-- resources.qrc -->
<RCC>
<qresource prefix="/icons">
<file>icons/save.png</file>
<file>icons/open.png</file>
</qresource>
<qresource prefix="/styles">
<file>styles/dark.qss</file>
</qresource>
<qresource prefix="/">
<file>config.json</file>
</qresource>
</RCC>
// 代码中使用
QPixmap(":/icons/save.png"); // prefix + 文件名
QIcon(":/icons/open.png");
setStyleSheet(loadFile(":/styles/dark.qss"));
// 路径规则::/前缀/文件名
// ⚠️ 路径大小写敏感
CMake 配置
qt_add_resources(MyApp "app_resources"
PREFIX "/"
FILES
resources.qrc
)
国际化 (i18n) 三步走
第一步:代码中用 tr()
// 所有用户可见字符串用 tr() 包裹
label->setText(tr("Hello World"));
button->setText(tr("Save"));
// tr() 支持参数
statusBar()->showMessage(tr("%1 files processed").arg(count));
// 处理复数
tr("%n file(s) saved", "", n); // n=1 时显示 "1 file saved"
// QObject 子类自动有 tr();非 QObject 用 QCoreApplication::translate()
QCoreApplication::translate("MyClass", "Hello");
第二步:生成 .ts 翻译文件
# 在 .pro 文件中声明
TRANSLATIONS = myapp_zh_CN.ts myapp_ja.ts
# 或用 lupdate 命令行
lupdate main.cpp widget.cpp -ts myapp_zh_CN.ts
生成的 .ts 文件结构:
<?xml version="1.0" encoding="utf-8"?>
<!DOCTYPE TS>
<TS version="2.1" language="zh_CN">
<context>
<name>MainWindow</name>
<message>
<source>Hello World</source>
<translation>你好,世界</translation>
</message>
</context>
</TS>
第三步:编译 .qm 并加载
# 用 Qt Linguist 编辑 .ts → 或用 lrelease 编译
lrelease myapp_zh_CN.ts # 生成 myapp_zh_CN.qm
#include <QTranslator>
int main(int argc, char *argv[]) {
QApplication app(argc, argv);
QTranslator translator;
if (translator.load(":/myapp_zh_CN.qm")) {
app.installTranslator(&translator);
}
// ...
return app.exec();
}
运行时语言切换
class LanguageManager {
QMap<QString, QTranslator *> m_translators;
public:
void install(const QString &lang, const QString &qmPath) {
auto *t = new QTranslator(this);
if (t->load(qmPath)) {
qApp->installTranslator(t);
m_translators.insert(lang, t);
}
}
void switchTo(const QString &lang) {
// 移除所有旧翻译
for (auto *t : m_translators)
qApp->removeTranslator(t);
// 安装目标语言
auto *t = m_translators.value(lang);
if (t) qApp->installTranslator(t);
// 通知所有控件刷新
emit languageChanged();
}
signals:
void languageChanged();
};
控件刷新
// QWidget 重写 changeEvent
void MainWindow::changeEvent(QEvent *event) override {
if (event->type() == QEvent::LanguageChange) {
// Qt 自动刷新通过 UI 文件创建的控件
// 手动设置的文字需要在这里重新设置
ui->retranslateUi(this); // 重新翻译 UI 文件
updateDynamicTexts(); // 手动更新的文字
}
QMainWindow::changeEvent(event);
}
void MainWindow::updateDynamicTexts() {
m_statusLabel->setText(tr("Ready"));
setWindowTitle(tr("My Application"));
}
常见问题
// ❌ 不要用 #define 或 const char * 存可翻译字符串
const char *msg = "Hello"; // lupdate 扫描不到宏定义
// ✅ 直接用 tr()
label->setText(tr("Hello"));
// ❌ 字符串拼接会破坏翻译查找
label->setText(tr("Hello " + name)); // 不好
// ✅ 用 %1 占位符
label->setText(tr("Hello %1").arg(name));
文件组织建议
project/
├── resources.qrc
├── icons/ # 图标 → 编译进 .qrc
│ ├── save.png
│ └── open.png
├── styles/ # QSS → 编译进 .qrc
│ ├── light.qss
│ └── dark.qss
└── translations/ # .ts/.qm — 不编译进 .qrc(太大)
├── myapp_zh_CN.ts
├── myapp_zh_CN.qm
├── myapp_ja.ts
└── myapp_ja.qm