前言
Qt 将我们常用的窗口封装成了标准对话框,常见的有 QFontDialog ,QColorDialog,QFileDialog,用起来非常方便…直到需要翻译。

由于标准对话框并非我们自己实现,所以翻译所需要的ts该如何生成呢?
对于一般的标准对话框,只需要找到其对于的ts,并将其对应的部分复制到我们的ts中就可以了。那么去哪里找呢?查找路径为安装路径(安装时记得安装源码)
例如:
QFontDialog 位于 D:\QT\QT5.9.3\5.9.3\Src\qttranslations\translations\qt_zh_CN.ts 中:
QColorDialog翻译的一些小问题:
Pick Screen Color 未翻译
查看源码 qcolordialog.cpp
void QColorDialog::changeEvent(QEvent *e)
{
Q_D(QColorDialog);
if (e->type() == QEvent::LanguageChange)
d->retranslateStrings();
QDialog::changeEvent(e);
}
void QColorDialogPrivate::retranslateStrings()
{
if (nativeDialogInUse)
return;
if (!smallDisplay) {
lblBasicColors->setText(QColorDialog::tr("&Basic colors"));
lblCustomColors->setText(QColorDialog::tr("&Custom colors"));
addCusBt->setText(QColorDialog::tr("&Add to Custom Colors"));
screenColorPickerButton->setText(QColorDialog::tr("&Pick Screen Color"));
}
cs->retranslateStrings();
}
只是我们 ts 中没有罢了,自己加上~
QColorDialog 中添加一段:
<context>
<name>QColorDialog</name>
//...
<message>
<source>&Pick Screen Color</source>
<translation>获取屏幕颜色</translation>
</message>
</context>
OK/Cancel未翻译的问题
经搜索,其实它是一个 QDialogButtonBox,因此在 qt_zh_CN.ts 中找到它并加上。
<context>
<name>QDialogButtonBox</name>
<message>
<location filename="../src/gui/dialogs/qmessagebox.cpp" line="+1866"/>
<location line="+464"/>
<location filename="../src/gui/widgets/qdialogbuttonbox.cpp" line="+561"/>
<source>OK</source>
<translation>确定</translation>
</message>
//...
<message>
<location line="+3"/>
<source>Cancel</source>
<translation>取消</translation>
</message>
<message>
<location line="+0"/>
<source>&Cancel</source>
<translation>取消(&C)</translation>
</message>
//...
</context>
然后就会发现还是不行…查找一下源码 qdialogbuttonbox.cpp
bool QDialogButtonBox::event(QEvent *event)
{
Q_D(QDialogButtonBox);
if (event->type() == QEvent::Show) {
QList<QAbstractButton *> acceptRoleList = d->buttonLists[AcceptRole];
QPushButton *firstAcceptButton = acceptRoleList.isEmpty() ? 0 : qobject_cast<QPushButton *>(acceptRoleList.at(0));
bool hasDefault = false;
QWidget *dialog = 0;
QWidget *p = this;
while (p && !p->isWindow()) {
p = p->parentWidget();
if ((dialog = qobject_cast<QDialog *>(p)))
break;
}
const auto pbs = (dialog ? dialog : this)->findChildren<QPushButton *>();
for (QPushButton *pb : pbs) {
if (pb->isDefault() && pb != firstAcceptButton) {
hasDefault = true;
break;
}
}
if (!hasDefault && firstAcceptButton)
firstAcceptButton->setDefault(true);
}else if (event->type() == QEvent::LanguageChange) {
d->retranslateStrings();
}
return QWidget::event(event);
}
void QDialogButtonBoxPrivate::retranslateStrings()
{
typedef QHash<QPushButton *, QDialogButtonBox::StandardButton>::iterator Iterator;
const Iterator end = standardButtonHash.end();
for (Iterator it = standardButtonHash.begin(); it != end; ++it) {
const QString text = QGuiApplicationPrivate::platformTheme()->standardButtonText(it.value());
if (!text.isEmpty())
it.key()->setText(text);
}
}
// 跟踪到QGuiApplicationPrivate::platformTheme()->standardButtonText(it.value());
QString QPlatformTheme::standardButtonText(int button) const
{
return QPlatformTheme::defaultStandardButtonText(button);
}
QString QPlatformTheme::defaultStandardButtonText(int button)
{
switch (button) {
case QPlatformDialogHelper::Ok:
return QCoreApplication::translate("QPlatformTheme", "OK");
case QPlatformDialogHelper::Save:
return QCoreApplication::translate("QPlatformTheme", "Save");
case QPlatformDialogHelper::SaveAll:
return QCoreApplication::translate("QPlatformTheme", "Save All");
case QPlatformDialogHelper::Open:
return QCoreApplication::translate("QPlatformTheme", "Open");
case QPlatformDialogHelper::Yes:
return QCoreApplication::translate("QPlatformTheme", "&Yes");
case QPlatformDialogHelper::YesToAll:
return QCoreApplication::translate("QPlatformTheme", "Yes to &All");
case QPlatformDialogHelper::No:
return QCoreApplication::translate("QPlatformTheme", "&No");
case QPlatformDialogHelper::NoToAll:
return QCoreApplication::translate("QPlatformTheme", "N&o to All");
case QPlatformDialogHelper::Abort:
return QCoreApplication::translate("QPlatformTheme", "Abort");
case QPlatformDialogHelper::Retry:
return QCoreApplication::translate("QPlatformTheme", "Retry");
case QPlatformDialogHelper::Ignore:
return QCoreApplication::translate("QPlatformTheme", "Ignore");
case QPlatformDialogHelper::Close:
return QCoreApplication::translate("QPlatformTheme", "Close");
case QPlatformDialogHelper::Cancel:
return QCoreApplication::translate("QPlatformTheme", "Cancel");
case QPlatformDialogHelper::Discard:
return QCoreApplication::translate("QPlatformTheme", "Discard");
case QPlatformDialogHelper::Help:
return QCoreApplication::translate("QPlatformTheme", "Help");
case QPlatformDialogHelper::Apply:
return QCoreApplication::translate("QPlatformTheme", "Apply");
case QPlatformDialogHelper::Reset:
return QCoreApplication::translate("QPlatformTheme", "Reset");
case QPlatformDialogHelper::RestoreDefaults:
return QCoreApplication::translate("QPlatformTheme", "Restore Defaults");
default:
break;
}
return QString();
}
原来它调用的是 QPlatformTheme,怪不得翻译无效…
遗憾的是 qt_zh_CN.ts 中没有,经查,该翻译位于 qtbase_xx.ts 。
如今已经不提供 qtbase_zh.ts 了,所以自行翻译吧:
<context>
<name>QPlatformTheme</name>
<message>
<source>OK</source>
<translation>确认</translation>
</message>
<message>
<source>Cancel</source>
<translation>取消</translation>
</message>
</context>
总结:Qt 原生组件翻译技巧
- 通过
https://code.woboq.org/查看源码 / 百度等方式确定你要翻译的 类名。
(eg:QPlainTextEdit右键出来的窗体是QWidgetTextControl,所以我们要翻译应该找QWidgetTextControl) - 安装qt源码,找到
src\qttranslations路径下的qttranslations.pro,打开工程,查找第一步找到的类名。截取加入到我们的ts中。

4903

被折叠的 条评论
为什么被折叠?



