Название: Qt: как перевести кнопки в qmessagebox?

У меня есть QMessageBox:

QMessageBox::question(this, tr("Sure want to quit?"), 
    tr("Sure to quit?"), QMessageBox::Yes | QMessageBox::No);

Как я могу перевести слово "Да/Нет"? так как нет места для размещения tr()?

Ответ 1

Извините, я опаздываю, но есть лучший способ решить вашу проблему.

Правильный способ - не переводить эти строки вручную. Qt уже включает переводы в папку translation.

Идея заключается в загрузке переводов (qm файлов), включенных в Qt.

Я хотел бы показать вам код для перевода сообщения в соответствии с вашим языком:

#include <QDebug>
#include <QtWidgets/QApplication>
#include <QMessageBox>
#include <QTranslator>
#include <QLibraryInfo>

int main(int argc, char *argv[])
{

    QApplication app(argc, argv);

    QTranslator qtTranslator;
    if (qtTranslator.load(QLocale::system(),
                "qt", "_",
                QLibraryInfo::location(QLibraryInfo::TranslationsPath)))
    {
        qDebug() << "qtTranslator ok";
        app.installTranslator(&qtTranslator);
    }

    QTranslator qtBaseTranslator;
    if (qtBaseTranslator.load("qtbase_" + QLocale::system().name(),
                QLibraryInfo::location(QLibraryInfo::TranslationsPath)))
    {
        qDebug() << "qtBaseTranslator ok";
        app.installTranslator(&qtBaseTranslator);
    }

    QMessageBox::question(0, QObject::tr("Sure want to quit?"), QObject::tr("Sure to quit?"), QMessageBox::Yes | QMessageBox::No);

    return app.exec();
}

Примечания:

  • Вы можете загрузить другое местоположение, создав новый объект QLocale и установив его с помощью void QLocale::setDefault(const QLocale & locale). Пример.
  • Я загружаю qt_*.qm и qtbase_*.qm, потому что с Qt 5.3 переводы расщепляются в разных файлах. Фактически, для QMessageBox переведенные строки находятся в qtbase_*.qm. Истина является хорошей практикой. Подробнее. Существует больше файлов qm, таких как qtquickcontrols_*.qm или qtmultimedia_*qm. Загрузите требуемые в соответствии с вашими требованиями.
  • Возможно, вы можете найти текст, который вы пытаетесь перевести, еще не переведен на Qt. В этом случае я рекомендую вам обновить версию Qt, чтобы проверить, существует ли перевод в самой последней версии или код самостоятельно. Некоторые полезные ссылки: здесь и здесь.

Ответ 2

Это способ сделать это:

QMessageBox messageBox(QMessageBox::Question,
            tr("Sure want to quit?"),
            tr("Sure to quit?"),
            QMessageBox::Yes | QMessageBox::No,
            this);
    messageBox.setButtonText(QMessageBox::Yes, tr("Yes"));
    messageBox.setButtonText(QMessageBox::No, tr("No"));

И чтобы показать сообщение:

messageBox.exec();

Ответ 3

Нет причин для этого. Эти тексты локализованы в собственных файлах локализации Qt. Вам необходимо предоставить и, возможно, загрузить локализацию Qt в вашем приложении.

Ответ 4

Я написал специальный класс QMessageBoxEx для этой проблемы.

// init once your button texts
QMessageBoxEx::setCustomTextForButton(QMessageBox::Yes, "Да");
QMessageBoxEx::setCustomTextForButton(QMessageBox::No, "Нет");

// example usage
if (QMessageBoxEx::question(this, "Внимание", "Ошибка", QMessageBox::Yes | QMessageBox::No) == QMessageBox::Yes)
{
   // OK
}

// header

class QMessageBoxEx : public QMessageBox
{
private:

    static QMap<QMessageBox::StandardButton, QString> m_customButtonNames;

protected:

    static void setCustomTextForButtons(QMessageBoxEx &msgBox);

public:

    QMessageBoxEx(QWidget *parent);

    static void setCustomTextForButton(QMessageBox::StandardButton button, const QString &text);

    static QMessageBox::StandardButton critical(QWidget *parent, const QString &title, const QString &text, QMessageBox::StandardButtons buttons = QMessageBox::Ok, QMessageBox::StandardButton defaultButton = NoButton);
    static QMessageBox::StandardButton information(QWidget *parent, const QString &title, const QString &text, QMessageBox::StandardButtons buttons = QMessageBox::Ok, QMessageBox::StandardButton defaultButton = NoButton);
    static QMessageBox::StandardButton question(QWidget *parent, const QString &title, const QString &text, QMessageBox::StandardButtons buttons = QMessageBox::StandardButtons(QMessageBox::Yes | QMessageBox::No), QMessageBox::StandardButton defaultButton = QMessageBox::NoButton);
    static QMessageBox::StandardButton warning(QWidget *parent, const QString &title, const QString &text, QMessageBox::StandardButtons buttons = QMessageBox::Ok, QMessageBox::StandardButton defaultButton = NoButton);

};

// implementation

QMap<QMessageBox::StandardButton, QString> QMessageBoxEx::m_customButtonNames;

void QMessageBoxEx::setCustomTextForButton(QMessageBox::StandardButton button, const QString &text)
{
    if (m_customButtonNames.contains(button))
        m_customButtonNames.erase(m_customButtonNames.find(button));

    m_customButtonNames[button] = text;
}

void QMessageBoxEx::setCustomTextForButtons(QMessageBoxEx &msgBox)
{
    if (m_customButtonNames.size())
    {
        QMessageBox::StandardButtons buttons = msgBox.standardButtons();

        for (auto button : m_customButtonNames.keys())
        {
            if (buttons & button)
            {
                msgBox.setButtonText(button, m_customButtonNames[button]);
            }
        }
    }
}

QMessageBox::StandardButton QMessageBoxEx::critical(QWidget *parent, const QString &title, const QString &text, QMessageBox::StandardButtons buttons, QMessageBox::StandardButton defaultButton)
{
    QMessageBoxEx msgBox(parent);

    msgBox.setIcon(QMessageBox::Critical);
    msgBox.setWindowTitle(title);
    msgBox.setText(text);
    msgBox.setStandardButtons(buttons);
    msgBox.setDefaultButton(defaultButton);

    setCustomTextForButtons(msgBox);

    return (QMessageBox::StandardButton)msgBox.exec();
}

QMessageBox::StandardButton QMessageBoxEx::information(QWidget *parent, const QString &title, const QString &text, QMessageBox::StandardButtons buttons, QMessageBox::StandardButton defaultButton)
{
    QMessageBoxEx msgBox(parent);

    msgBox.setIcon(QMessageBox::Information);
    msgBox.setWindowTitle(title);
    msgBox.setText(text);
    msgBox.setStandardButtons(buttons);
    msgBox.setDefaultButton(defaultButton);

    setCustomTextForButtons(msgBox);

    return (QMessageBox::StandardButton)msgBox.exec();
}

QMessageBox::StandardButton QMessageBoxEx::question(QWidget *parent, const QString &title, const QString &text, QMessageBox::StandardButtons buttons, QMessageBox::StandardButton defaultButton)
{
    QMessageBoxEx msgBox(parent);

    msgBox.setIcon(QMessageBox::Question);
    msgBox.setWindowTitle(title);
    msgBox.setText(text);
    msgBox.setStandardButtons(buttons);
    msgBox.setDefaultButton(defaultButton);

    setCustomTextForButtons(msgBox);

    return (QMessageBox::StandardButton)msgBox.exec();
}

QMessageBox::StandardButton QMessageBoxEx::warning(QWidget *parent, const QString &title, const QString &text, QMessageBox::StandardButtons buttons, QMessageBox::StandardButton defaultButton)
{
    QMessageBoxEx msgBox(parent);

    msgBox.setIcon(QMessageBox::Warning);
    msgBox.setWindowTitle(title);
    msgBox.setText(text);
    msgBox.setStandardButtons(buttons);
    msgBox.setDefaultButton(defaultButton);

    setCustomTextForButtons(msgBox);

    return (QMessageBox::StandardButton)msgBox.exec();
}

QMessageBoxEx::QMessageBoxEx(QWidget *parent) : QMessageBox(parent)
{

}

Gist: https://gist.github.com/kleuter/81a75a50e60a75aa0370a66ededc0c31

Ответ 5

Обновление: Я нашел в D:\Qt\Qt5.7.0\5.7\Src\qttranslations\translations\qtbase _ **. У ts уже есть файл трансляции QPlatformTheme (к сожалению, нет qtbase_zh_CN.ts), вы также можете скопировать qtbase_ * *.ts и немедленно изменить его. Если вы такой же китайский, как я, спасибо wisaly (github), он уже перевел qtbase на китайский, и здесь мой вилка на github.


После чтения исходного кода Qt я решил эту проблему. (Моя версия Qt - Qt 5.7.0 и установлена ​​в C:\Qt\Qt5.7.0 с Src)

Откройте файл C:\Qt\Qt5.7.0\5.7\Src\qtbase\src\gui\gui.pro и вставьте строку, как показано ниже, для создания китайского файла перевода:

TRANSLATIONS    +=  gui_zh.ts

Откройте проект gui.pro с помощью Qt Creator и используйте lupdate, чтобы создать новый оригинальный исходный файл перевода с именем gui_zh.ts.

Откройте qui_zh.ts с помощью Linguist и переведите элемент QPlatformTheme. Здесь только перевод "& Yes" в качестве примера: введите описание изображения здесь

После перевода используйте lrelease для создания файла двоичного перевода (gui_zh.qm).

Наконец, загрузите файлы переводов (gui_zh.qm) в QApplication, текст кнопки QMessageBox будет в порядке.

Мои результаты:

QMessageBox::information(this,
    QString("警告"),
    QString("测试文本"),
    QMessageBox::Yes | QMessageBox::No
);

введите описание изображения здесь

Кстати, вы также можете использовать этот метод для разрешения правильных проблем перекрестных контекстов некоторых QWidgets, таких как QTextEdit, путем добавления переводов в C:\Qt\Qt5.7.0\5.7\Src\qtbase\src\widgets\widgets. про.