QT 4: программирование GUI на С++
Шрифт:
Для всех этих кодировок функция QTextCodec::codecForName всегда будет возвращать достоверный указатель. Другие кодировки можно обеспечить путем создания подкласса QTextCodec.
Создание переводимого интерфейса приложения
Если мы хотим иметь многоязыковую версию нашего приложения, мы должны сделать две вещи:
• убедиться, что все строки, которые видит пользователь, проходят через функцию tr;
• загрузить файл перевода (.qm) при запуске приложения.
Ничего
Функция tr является статической функцией, определенной в классе QObject и переопределяемой в каждом подклассе, в котором встречается макрос Q_OBJECT. При ее использовании в рамках подкласса QObject мы можем вызывать tr без ограничений. Вызов tr возвращает перевод строки, если он имеется, и первоначальный текст в противном случае.
Для подготовки файлов переводов мы должны запустить утилиту Qt lupdate. Эта утилита собирает все строковые константы, которые встречаются в вызовах tr, и формирует файлы переводов, содержащие все эти подготовленные к переводу строки. Эти файлы могут затем быть переданы переводчику для добавления к ним перевода строк. Эта процедура рассматривается позже в данной главе в разделе «Перевод приложений».
В общем виде вызов tr имеет следующий синтаксис:
Здесь Контекст — имя подкласса QObject, в котором используется макрос Q_OBJECT. Нам не требуется его указывать, если мы вызываем tr в функции—члене рассматриваемого класса. Аргумент исходныйТекст — текстовая константа, которую нужно будет переводить. Аргумент комментарий является необязательным, и он может использоваться для предоставления переводчику дополнительной информации.
Ниже приводится несколько примеров:
Первые два вызова tr выполняются в контексте объекта RockyWidget (скалистый виджет), а вторые два — в контексте объекта SnazzyDialog (притягательное диалоговое окно). В качестве исходного текста во всех четырех случаях используется слово «Letter» (буква). Последний вызов имеет также комментарий, помогающий переводчику точнее понять смысл исходного текста.
Строки в различных контекстах (классах) переводятся независимо друг от друга. Переводчики, как правило, одновременно работают только с одним
Когда мы вызываем tr из глобальной функции, мы должны явно указать контекст. Любой подкласс QObject может использоваться в приложении в качестве контекста. Если такого подкласса нет, мы всегда можем использовать сам класс QObject. Например:
До сих пор во всех примерах контекст задавался именем класса. Это удобно, поскольку мы почти всегда можем опустить его, но на самом деле это не так. Наиболее общий способ перевода строки в Qt заключается в использовании функции QApplication::translate, которая принимает три аргумента: контекст, исходный текст и необязательный комментарий. Например, ниже приводится другой способ перевода «Hello Qt!»:
На этот раз мы поместили текст в контекст «Global Stuff» (глобальное вещество — ну нихрена себе перевод :) ).
Функции tr и translate играют двоякую роль: они являются маркерами, которые утилита lupdate использует для поиска видимых пользователем строк, и одновременно они являются функциями С++, которые переводят текст. Это отражается на том, как следует записывать программный код. Например, следующий программный код не сработает:
Проблема состоит в том, что утилита lupdate не сможет извлечь строковую константу «OpenDrawer 2D», поскольку она не входит в вызов функции tr. Это означает, что переводчик не будет иметь возможность перевести эту строку. Эта проблема часто возникает и при построении динамических строк:
Здесь значение строки, которую мы передаем функции tr, меняется в зависимости от значения hostName, и поэтому мы не можем ожидать, что перевод функцией tr будет выполнен правильно.
Решение заключается в применении функции QString::arg:
Обратите внимание на то, как это работает: строковый литерал «Host %1 found» (хост %1 найден) передается функции tr. Если загружен файл перевода на французский язык, tr возвратит что-то подобное «Нфtе %1 trouvй». Параметр «%1» замещается на содержимое переменной hostName.