I have a QMessageBox
like this:
QMessageBox::question(this, tr("Sure want to quit?"),
tr("Sure to quit?"), QMessageBox::Yes | QMessageBox::No);
How could I translate the Yes/No word? since there is no place to place a tr()
?
Sorry, I'm late, but there is a best way of solving your issue.
The right way is not to manually translate those strings. Qt already includes translations in the translation
folder.
The idea is to load the translations (qm
files) included in Qt.
I'd like to show you a code to get the message translated according to your locale:
#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();
}
Notes:
void QLocale::setDefault(const QLocale & locale)
. Example.qt_*.qm
and qtbase_*.qm
because since Qt 5.3 the translations are splited in different files. In fact, for QMessageBox
the translated strings are in qtbase_*.qm
. Loading both is a good practice. More info. There are more qm
files like qtquickcontrols_*.qm
or qtmultimedia_*qm
. Load the required ones according to your requirements.This is the way to do that:
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"));
And to show the message:
messageBox.exec();
update: I found in D:\Qt\Qt5.7.0\5.7\Src\qttranslations\translations\qtbase_**.ts already has the QPlatformTheme's translation srouce file (Unfortunately, there is no qtbase_zh_CN.ts), you can also copy a qtbase_**.ts and modify it immediately. If you are a Chinese like me, thanks to wisaly(github), he has already translated the qtbase to Chinese, and here is my fork on github.
After reading the Qt source code, I solved this issue. (My Qt's version is Qt 5.7.0, and installed in C:\Qt\Qt5.7.0 with Src)
Open the C:\Qt\Qt5.7.0\5.7\Src\qtbase\src\gui\gui.pro and insert a line like below to generate a Chinese translation file:
TRANSLATIONS += gui_zh.ts
Open the gui.pro project with Qt Creator and use lupdate to generate a new cute's translation source file named gui_zh.ts.
Open the qui_zh.ts using Linguist and translate the QPlatformTheme item. Here only translated “&Yes” as a example:
After translated, use lrelease to generate a binary translation file (gui_zh.qm).
Lastly, load the translations files (gui_zh.qm) to your QApplication, the button's text of QMessageBox will be ok.
My results are:
QMessageBox::information(this,
QString("警告"),
QString("测试文本"),
QMessageBox::Yes | QMessageBox::No
);
By the way, you can also use this method to sovle the right contextmenu's transtions issues of some QWidgets like QTextEdit by add translations to C:\Qt\Qt5.7.0\5.7\Src\qtbase\src\widgets\widgets.pro.
I wrote a special QMessageBoxEx class for this issue.
// 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
There's no reason to do this. These texts are localized in Qt's own localization files. You need to provide, and perhaps also load, Qt's localizations within your application.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With