Чтение онлайн

ЖАНРЫ

QT 4: программирование GUI на С++

Саммерфилд Марк

Шрифт:

Контекст::tr(исходныйТекст, комментарий)

Здесь Контекст — имя подкласса QObject, в котором используется макрос Q_OBJECT. Нам не требуется его указывать, если мы вызываем tr в функции—члене рассматриваемого класса. Аргумент исходныйТекст — текстовая константа, которую нужно будет переводить. Аргумент комментарий является необязательным, и он может использоваться для предоставления переводчику дополнительной информации.

Ниже приводится несколько примеров:

01 RockyWidget::RockyWidget(QWidget *parent)

02 : QWidget(parent)

03 {

04 QString str1 = tr("Letter");

05 QString str2 = RockyWidget::tr("Letter");

06 QString str3 = SnazzyDialog::tr("Letter");

07 QString str4 = SnazzyDialog::tr("Letter", "US paper size");

08 }

Первые

два вызова tr выполняются в контексте объекта RockyWidget (скалистый виджет), а вторые два — в контексте объекта SnazzyDialog (притягательное диалоговое окно). В качестве исходного текста во всех четырех случаях используется слово «Letter» (буква). Последний вызов имеет также комментарий, помогающий переводчику точнее понять смысл исходного текста.

Строки в различных контекстах (классах) переводятся независимо друг от друга. Переводчики, как правило, одновременно работают только с одним контекстом, причем часто при этом работает приложение и на экране отображается виджет или диалоговое окно, которые необходимо перевести.

Когда мы вызываем tr из глобальной функции, мы должны явно указать контекст. Любой подкласс QObject может использоваться в приложении в качестве контекста. Если такого подкласса нет, мы всегда можем использовать сам класс QObject. Например:

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

02 {

03 QApplication app(argc, argv);

04 QPushButton button(QObject::tr("Hello Qt!"));

05 button.show;

06 return app.exec;

07 }

До сих пор во всех примерах контекст задавался именем класса. Это удобно, поскольку мы почти всегда можем опустить его, но на самом деле это не так. Наиболее общий способ перевода строки в Qt заключается в использовании функции QApplication::translate, которая принимает три аргумента: контекст, исходный текст и необязательный комментарий. Например, ниже приводится другой способ перевода «Hello Qt!»:

QApplication::translate("Global Stuff", "Hello Qt!");

На этот раз мы поместили текст в контекст «Global Stuff» (глобальное вещество — ну нихрена себе перевод :) ).

Функции tr и translate играют двоякую роль: они являются маркерами, которые утилита lupdate использует для поиска видимых пользователем строк, и одновременно они являются функциями С++, которые переводят текст. Это отражается на том, как следует записывать программный код. Например, следующий программный код не сработает:

// НЕПРАВИЛЬНО

const char *appName = "OpenDrawer 2D";

QString translated = tr(appName);

Проблема состоит в том, что утилита lupdate не сможет извлечь строковую константу «OpenDrawer 2D», поскольку она не входит в вызов функции tr. Это означает, что переводчик не будет иметь возможность перевести эту строку. Эта проблема часто возникает и при построении динамических строк:

// НЕПРАВИЛЬНО

statusBar->showMessage(tr("Host " + hostName + " found"));

Здесь значение строки, которую мы передаем функции tr, меняется в зависимости от значения hostName, и поэтому мы не можем ожидать, что перевод функцией tr будет

выполнен правильно.

Решение заключается в применении функции QString::arg:

statusBar->showMessage(tr("Host %1 found").arg(hostName));

Обратите внимание на то, как это работает: строковый литерал «Host %1 found» (хост %1 найден) передается функции tr. Если загружен файл перевода на французский язык, tr возвратит что-то подобное «Нфtе %1 trouvй». Параметр «%1» замещается на содержимое переменной hostName.

Хотя в целом не рекомендуется вызывать tr для переменной, это может сработать. Мы должны использовать макрос QT_TR_NOOP для пометки тех строковых литералов, перевод которых должен быть выполнен до их присваивания переменной. Это лучше всего делать для статических массивов строк. Например:

01 void OrderForm::init

02 {

03 static const char * const flowers[] = {

04 QT_TR_NOOP("Medium Stem Pink Roses"),

05 QT_TR_NOOP("One Dozen Boxed Roses"),

06 QT_TR_NOOP("Calypso Orchid"),

07 QT_TR_NOOP("Dried Red Rose Bouquet"),

08 QT_TR_NOOP("Mixed Peonies Bouquet"),

09 0

10 };

11 for (int i = 0; flowers[i]; ++i)

12 comboBox->addItem(tr(flowers[i]));

13 }

Макрос QT_TR_NOOP просто возвращает свой аргумент. Но утилита lupdate обнаружит все строки, заданные в виде аргумента макроса QT_TR_NOOP, и поэтому они смогут быть переведены. При использовании позже этой переменной мы вызываем, как обычно, tr для выполнения перевода. Несмотря на передачу функции tr переменной, перевод все-таки будет выполнен.

Существует также макрос QT_TRANSLATE_NOOP, который работает подобно макросу QT_TR_NOOP, но для него, кроме того, задается контекст. Этот макрос удобно использовать для инициализации переменных вне класса:

static const char * const flowers[] = {

QT_TRANSLATE_NOOP("OrderForm", "Medium Stem Pink Roses"),

QT_TRANSLATE_NOOP("OrderForm", "One Dozen Boxed Roses"),

QT_TRANSLATE_NOOP("OrderForm", "Calypso Orchid"),

QT_TRANSLATE_NOOP("OrderForm", "Dried Red Rose Bouquet"),

QT_TRANSLATE_NOOP("OrderForm", "Mixed Peonies Bouquet"),

0

};

Здесь аргумент контекста должен совпадать с контекстом при будущем вызове функции tr или translate.

Когда мы начинаем использовать в приложении функцию tr, легко можно забыть в каких-то случаях о необходимости задавать видимые пользователем строки через вызов функции tr (особенно если это делается впервые). Эти пропущенные строки фактически могут быть обнаружены переводчиком или, еще хуже, пользователями переведенного приложения, когда некоторые строки будут отображаться с применением первоначального языка. Чтобы не допустить этого, мы можем указать Qt на необходимость запрета неявных преобразований с типа const char * на тип QString. Это делается путем определения препроцессорного символа QT_NO_CAST_FROM_ASCII перед включением любого заголовочного файла Qt. Наиболее простой способ обеспечения установки этого символа состоит в добавлении следующей строки в файл .pro:

Поделиться с друзьями: