По-умолчанию, Qt интерпретирует аргументы функции tr() как Latin-1. Чтобы установить иную кодировку, нужно вызвать статическую функциюQTextCodec::setCodecForTr(), например:
QTextCodec *japaneseCodec = QTextCodec::codecForName("EUC-JP");
QTextCodec::setCodecForTr(japaneseCodec);
Это должно быть сделано перед самым первым вызовом функции tr(). Как правило это делается в функции main(), после создания объекта QApplication.
Но все остальные строки в программе, по прежнему будут интерпретироваться как Latin-1. Если программист хочет записать японские иероглифы в строковую переменную, он должен выполнить явное преобразование в Unicode:
QString text = japaneseCodec->toUnicode("
");
Как альтернатива -- установить соответствующий кодек для выполнения преобразований между const char * и QString, вызовомQTextCodec::setCodecForCStrings():
QTextCodec::setCodecForCStrings(japaneseCodec);
Техника, описанная выше, может применяться к любой кодировке, не являющейся Latin-1, включая Китайскую, Греческую, Корейскую и Русскую. Ниже приводится список кодировок, поддерживаемых библиотекой Qt 3.2:
· Apple Roman | · CP1258 | · ISO 8859-4 | · ISO 8859-15 |
· Big5-HKSCS | · EUC-JP | · ISO 8859-5 | · ISO 10646 UCS-2 |
· CP874 | · EUC-KR | · ISO 8859-6 | · JIS7 |
· CP1250 | · GB2312 | · ISO 8859-7 | · KOI8-R |
· CP1251 | · GB18030 | · ISO 8859-8 | · KOI8-U |
· CP1252 | · GBK | · ISO 8859-8-I | · Shift-JIS |
· CP1253 | · IBM-850 | · ISO 8859-9 | · TIS-620 |
· CP1254 | · IBM-866 | · ISO 8859-10 | · TSCII |
· CP1255 | · ISO 8859-1 | · ISO 8859-11 | · UTF-8 |
· CP1256 | · ISO 8859-2 | · ISO 8859-13 | |
· CP1257 | · ISO 8859-3 | · ISO 8859-14 |
Для каждой из них, QTextCodec::codecForName() возвращает правильное значение. Поддержка других кодировок может быть реализована либо путем создания производного класса от QTextCodec, либо созданием файла-карты (charmap) и последующим использованием QTextCodec::loadCharmapFile().
15.2. Разработка приложений, подготовленных к переводу.
Если необходимо предусмотреть возможность перевода приложения на разные языки, следует соблюдать следующие положения:
· Весь текст, который будет отображаться перед пользователем, должен пропускаться через функцию tr().
· На запуске, приложение должно подгружать файл с переводом (.qm).
Эти условия не являются обязательными для приложений, которые никогда не будут переведены на другие языки. Однако, использование функции tr() не настолько обременительно, чтобы отказываться от нее. К тому же, тем самым вы оставляете открытой возможность локализации приложения в будущем.
Функция tr() -- статическая, она определена в классе QObject и перекрывается в каждом классе-потомке, который включает в свое определение макрос Q_OBJECT. Она возвращает перевод заданной строки, если он существует, или оригинальную версию строки -- в противном случае.
Для подготовки файла перевода необходимо запустить утилиту Qt -- lupdate. Она извлечет из исходного текста программы все строки, которые передаются функцииtr() и создаст файл перевода. Этот файл может быть передан переводчику, который добавит в него перевод для каждой из строк. Более подробно процесс перевода описан в разделе Перевод существующих приложений.
Функция tr() имеет следующий синтаксис вызова:
Context::tr(sourceText, comment)
Часть имени Context -- это имя класса, производного от QObject. Если функция вызывается в контексте класса, то указание имени класса не обязательно. sourceText-- это строка символов, которая должна быть переведена. comment -- не обязательный аргумент, может использоваться для предоставления дополнительной информации переводчику.
Еще один пример:
BlueWidget::BlueWidget(QWidget *parent, const char *name)
: QWidget(parent, name)
{
QString str1 = tr("Legal");
QString str2 = BlueWidget::tr("Legal");
QString str3 = YellowDialog::tr("Legal");
QString str4 = YellowDialog::tr("Legal", "US paper size");
}
Первые два вызова производятся в контексте класса BlueWidget, последние два --YellowDialog. Все четыре вызова получают строку "Legal" в качестве исходной, кроме того, последний из них имеет дополнительный комментарий, который поможет переводчику понять смысл исходной строки.
Перевод строк в разных контекстах выполняется независимо друг от друга. Переводчики обычно учитывают контекст в своей работе, часто выполняя пробные запуски приложения и оценивая качество перевода.
При вызове tr() из глобальных функций, необходимо явно указывать контекст, в качестве которого может использоваться любой класс, наследник от QObject. Если в приложении нет ничего подходящего, всегда можно прибегнуть к услугам самогоQObject, например:
int main(int argc, char *argv[])
{
QApplication app(argc, argv);
...
QPushButton button(QObject::tr("Hello Qt!"), 0);
app. setMainWidget(&button);
button. show();
return app. exec();
}
Очень часто полезной оказывается следующая методика, которая может быть применена к переводу названия приложения: вместо того, чтобы всякий раз набивать строки с именем приложения и вынуждать переводчика переводить их для каждого из контекстов, в котором они используются, более удобным будет определить его в виде макроса APPNAME, поместить макрос в заголовочный файл и использовать его по мере необходимости:
#define APPNAME MainWindow::tr("OpenDrawer 2D")
До сих пор, в качестве контекста мы рассматривали имя класса. Это довольно удобно, поскольку в большинстве случаев мы можем не указывать контекст перевода явно, при вызове функции tr(). Но более универсальный способ подготовки строк к переводу состоит в использовании функции QApplication:: translate(), которая принимает три аргумента: контекст, исходный текст и необязательный комментарий. Например, еще один способ определения макроса APPNAME:
#define APPNAME qApp->translate("Global Stuff", "OpenDrawer 2D")
На этот раз текст помещен в контекст "Global Stuff".
Функции tr() и translate() имеют двойное назначение: они служат маркерами для утилиты lupdate и в то же самое время -- это обычные функции C++, которые выполняют перевод текста. Такая двойственность накладывает некоторые ограничения на то, как записывается исходный код. Например, следующий отрывок не будет выполнять перевод строки на другой язык:
// НЕВЕРНО
const char *appName = "OpenDrawer 2D";
QString translated = tr(appName);
Проблема состоит в том, что lupdate не сможет отыскать строку "OpenDrawer 2D", поскольку она явно не передается функции tr(). Эта проблема очень часто проявляется при работе с динамическими строками:
// НЕВЕРНО
statusBar()->message(tr("Host " + hostName + " found"));
Здесь строка изменяется динамически, в зависимости от значения переменнойhostName, таким образом мы не можем требовать от tr() корректного перевода.
Как одно из решений проблемы -- используйте QString::arg():
statusBar()->message(tr("Host %1 found").arg(hostName));
Остановимся в этом месте чуть подробнее: функции tr() передается строка символов "Host %1 found". Допустим, что приложение загрузило файл с русским переводом, тогда функция tr() должна вернуть примерно такую строку: "Обнаружен узел сети %1". После этого аргумент '%1' замещается содержимым переменной hostName. В результате мы получаем вполне корректный перевод сообщения, которое демонстрируется русскоговорящему пользователю.
В случае, когда необходимо записать перевод строки в переменную, следует использовать макрос QT_TR_NOOP(). Чаще всего этот прием используется при создании статических массивов строк, например:
void OrderForm::init()
{
static const char * const flowers[] = {
QT_TR_NOOP("Medium Stem Pink Roses"),
QT_TR_NOOP("One Dozen Boxed Roses"),
QT_TR_NOOP("Calypso Orchid"),
QT_TR_NOOP("Dried Red Rose Bouquet"),
QT_TR_NOOP("Mixed Peonies Bouquet"),
|
Из за большого объема этот материал размещен на нескольких страницах:
1 2 3 4 5 |


