天天看點

Qt - 标準對話框翻譯

文章目錄

    • 前言
    • QColorDialog翻譯的一些小問題:
      • Pick Screen Color 未翻譯
      • OK/Cancel未翻譯的問題
    • 總結:Qt 原生元件翻譯技巧

前言

Qt

将我們常用的視窗封裝成了标準對話框,常見的有

QFontDialog

QColorDialog

QFileDialog

,用起來非常友善…直到需要翻譯。

Qt - 标準對話框翻譯

由于标準對話框并非我們自己實作,是以翻譯所需要的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>&amp;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>&amp;Cancel</source>
        <translation>取消(&amp;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

    中。

繼續閱讀