Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

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.

like image 370
MatthiaZ Avatar asked Nov 10 '22 08:11

MatthiaZ


1 Answers

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.

like image 117
Oleg Derevenetz Avatar answered Nov 26 '22 04:11

Oleg Derevenetz