文章目錄
-
- 前言
- QColorDialog翻譯的一些小問題:
-
- Pick Screen Color 未翻譯
- OK/Cancel未翻譯的問題
- 總結:Qt 原生元件翻譯技巧
前言
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