Как записать исходную строку QObject::tr и по-прежнему отображать в GUI перевод?

В моем проекте мы хотим перевести пользовательский интерфейс, но вести технические журналы на английском языке. Я согласен, что эти два вида сообщений должны оставаться разделенными, но иногда у нас есть некоторые сообщения об ошибках, которые мы хотим отображать и регистрировать одновременно.
Используя QObject::tr, вы получите переведенную строку и не сможете получить исходную строку.

Как я могу управлять журналом оригинальной версии + отображением переведенной версии без копирования / вставки?
Я открыт для любых предложений, включая ограничения дизайна.

1 ответ

Я решил эту проблему в одном из своих собственных проектов, введя специальный вспомогательный класс, содержащий как исходную, так и переведенную строку. Вот примерный набросок того, как это выглядит:

class LocalizedString
{
public:
    LocalizedString(const char * str) :
        m_originalString(str),
        m_localizedString(tr(str))
    {}

    const char * originalString() const { return m_originalString; }
    const QString & localizedString() const { return m_localizedString; }

private:
    const char *     m_originalString;
    QString          m_localizedString;
}

Тогда код, использующий этот класс, работает так:

// In one place within the code:
LocalizedString errorDescription = QT_TR_NOOP("Some message which should go both to the log and to the user");
qDebug() << errorDescription.originalString();
<...>
// In some other place within the code which gets errorDescription variable from somewhere and needs to show it to the user
showErrorMessage(errorDescription.localizedString());

Основной частью подхода является использование макроса QT_TR_NOOP. Он помечает вложенный в него строковый литерал как тот, который требует извлечения во время qmake шаг для дальнейшего перевода. В отличие от QObject::trэтот макрос не преобразует непереведенный текст в переведенный. Если вы хотите получить доступ к переведенному тексту, вам нужно позвонить tr позже вручную - как я делал в приведенном выше примере в конструкторе LocalizedString,

Обратите внимание, что QT_TR_NOOP разработан для использования внутри классов, т.е. контекст для перевода будет именем класса внутри некоторого метода, в котором присутствует макрос. Если у вас есть автономные функции или вы хотите сами указать контекст, используйте вместо этого макрос QT_TRANSLATE_NOOP - его вторым аргументом является контекст перевода.

Upd.: еще один совет: в моей реальной реализации LocalizedString она имеет operator<< который печатает оригинальную нелокализованную строку. Это удобно, потому что таким образом вы можете просто передать объект LocalizedString класс для QDebug не называя его originalString метод.

Другие вопросы по тегам