How to translate default qsTr fields - e.g. MessageDialog Yes / No buttons

I have a small app that uses a Qt Quick MessageDialog. I created translations files with command

lupdate-qt5 ../myapp.pro . 

In myapp.pro I indicated:

lupdate_only {
    SOURCES +=  $$PWD/ui/*.qml
} 

and

TRANSLATIONS += \
   translations/i18n_nl.ts translations/i18n_fr.ts translations/i18n_en.ts

All translations are generated correctly. But I have no idea how to generate translations for the standard buttons that MessageDialog provides. In the following example the translations for "Warning" and "Please select Yes or No" are generated. But I can't get them generated for "Yes" and "No" (which is the text value of the StandardButtons property)

MessageDialog {
    title: qsTr("Warning")
    text: qsTr("Please select Yes or No")
    icon: StandardIcon.Warning
    standardButtons: StandardButton.Yes | StandardButton.No
    //.....
}

I have checked the source code and it indicates that they should be translated:

Button {
    id: yesButton
    text: qsTr("Yes")
    onClicked: root.click(StandardButton.Yes)
    visible: root.standardButtons & StandardButton.Yes
}

I've also tried manually adding an entry Yes and No but that doesn't seem to help.

I've found an issue on stackoverflow that talks about adding the qml file to the .pro file to make it work, and that is something I already do. I though about adding the built-in MessageDialog, but I have no idea how to do this.

As a final note: I know that in Qt 5.3 the qsTr's weren't in MessageDialog. But starting from Qt 5.4 they are. I am currently on Qt 5.5

Any help is greatly appreciated.

EDIT

After posting this I kept looking and found an interesting post of someone who has had the same issue. Unfortunately, no answer there.

EDIT 2

Thank you tynn for the response. I have tried both suggestions but no succes. I did try something else as well. I added a qDebug in my code to see if it would translate. I was hoping the same translation would then be used for the MessageDialog, but unfortunatly that doesn't seem to be the case.

qDebug() << "Translate yes :" << tr("Yes"); //translates correctly, dialog doesn't

I have also tried to build a dialog from scratch that does the same as the built-in messagedialog, but at the moment my knowledge of qml is too limited to get this working.

Answers


The translations you need should be found inside a qtquickcontrols_*.qm file. Deploying Translations states concerning this

Usually, there are .qm files for the application, and, if a version of Qt is used that is not installed on the system, Qt's .qm files need to be deployed as well.

However your application might just fail to find a suitable translation file. If you only need the translations for Yes and No, you could as well add these to your translation files with a context of DefaultMessageDialog

<?xml version="1.0" encoding="utf-8"?>
<!DOCTYPE TS>
<TS version="2.1">
<context>
    <name>DefaultMessageDialog</name>
    <message>
        <source>Yes</source>
        <translation type="unfinished"></translation>
    </message>
    <message>
        <source>No</source>
        <translation type="unfinished"></translation>
    </message>
</context>
</TS>

Adding the built-in MessageDialog would work as well. Or if you'd like to, you could just use a dummy file DefaultMessageDialog.qml

Rectangle {
    Button {
        id: yesButton
        text: qsTr("Yes")
    }
    Button {
        id: noButton
        text: qsTr("No")
    }
}

and add this one instead.


Well, it may be a bit tricky.

First of all, localized strings for Qt widgets may be in Qt's .qm files. Remember that in general you will need all Qt's .qm files for locales you translate into. That's because Qt may, for example, use native MessageDialogs on platforms where they are available, and related code in this case will be located in qtbase, so you will need not only qtquickcontrols_XX.qm files, but also qtbase_XX.qm files for selected locales. And so on.

However, there may be cases when the above does not help. Required strings may simply be missing in the Qt's localization files for your locale (it's a quite common), so you will need to make .ts and .qm files for these strings by yourself. In this case you will need to study Qt sources in order to understand internals of those widgets you are interested in.

Please note that the following example depends on implementation details which may change in future Qt versions.

For example, Qt implementation of QML MessageDialog for Android and iOS uses QPlatformTheme that may be further subclassed to work with different platforms. In QPlatformTheme texts for button labels are returned by defaultStandardButtonText() method which looks like this:

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();
}

So, in order to localize Yes/No buttons, you will need to add in your .ts file the following:

<context>
    <name>QPlatformTheme</name>
    <message>
        <source>&amp;Yes</source>
        <translation>[...]</translation>
    </message>
    <message>
        <source>&amp;No</source>
        <translation>[...]</translation>
    </message>
</context>

Android have its own subclassed platform theme (QAndroidPlatformTheme) with overriden defaultStandardButtonText(), so for Android you will need to add the following:

<context>
    <name>QAndroidPlatformTheme</name>
    <message>
        <source>Yes</source>
        <translation>[...]</translation>
    </message>
    <message>
        <source>No</source>
        <translation>[...]</translation>
    </message>
</context>

iOS does not override this method in its own QPlatformTheme subclass, so no additional action is needed for it.

You can take a look on one of my projects which use the technique described above for QML MessageBox localization on Android and iOS.


Need Your Help

how to use group by on complex objects?

c# linq entity-framework

I am processing a complex object. The object has a list property of type public List&lt;ExcelDataRow&gt; DataRows

How to open a text file using Javascript from Adobe Indesign CS4?

javascript indesign

How can I open a text file, read the contents, and then insert the contents into a document in InDesign?