Russian Qt Forum

Qt => Интернационализация, локализация => Тема начата: QCasper от Сентябрь 06, 2006, 22:14



Название: QObject::tr() и lupdate
Отправлено: QCasper от Сентябрь 06, 2006, 22:14
Недавно начал изучать механизмы интернационализации, и вот вопрос. Все будет отлично если пихать все строки в tr(), например tr("string"), потом lupdate сделает нам файлик, который мы запихнем в лингвист, переведем, получим другой файлик, который и будем загружать в программе. А можно ли как-то обработать все это дело если у меня в tr() не сам литерал, а указатель на на строку например:

Код:
const char* c_string = "string";
tr(c_string);


в этом случае все дело заканчивается (по крайней мере для меня) тем, что lupdate ничего подходяещго для себя не находит. Как осуществлять перевод, если я хочу использовать константы?


Название: QObject::tr() и lupdate
Отправлено: Admin от Сентябрь 06, 2006, 22:17
скорее всего никак

если только макрос TR переписать


Название: QObject::tr() и lupdate
Отправлено: QCasper от Сентябрь 06, 2006, 22:37
Цитата: "Admin"
скорее всего никак

если только макрос TR переписать


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


Название: QObject::tr() и lupdate
Отправлено: DenKor от Сентябрь 07, 2006, 00:41
Смысла в этом особого нет.
Обычно (я например) пишут в макросе английиский текст. А далее занимаюсь переводом.

Константы можешь использовать спомощью дериктивы define


Название: QObject::tr() и lupdate
Отправлено: Вудруф от Сентябрь 07, 2006, 07:08
Из Assistant'а:
If you need to have translatable text completely outside a function, there are two macros to help: QT_TR_NOOP() and QT_TRANSLATE_NOOP(). They merely mark the text for extraction by the lupdate utility described below. The macros expand to just the text (without the context).
Example of QT_TR_NOOP():
    QString FriendlyConversation::greeting(int type)
    {
        static const char *greeting_strings[] = {
            QT_TR_NOOP("Hello"),
            QT_TR_NOOP("Goodbye")
        };
        return tr(greeting_strings[type]);
    }
Example of QT_TRANSLATE_NOOP():
    static const char *greeting_strings[] = {
        QT_TRANSLATE_NOOP("FriendlyConversation", "Hello"),
        QT_TRANSLATE_NOOP("FriendlyConversation", "Goodbye")
    };

    QString FriendlyConversation::greeting(int type)
    {
        return tr(greeting_strings[type]);
    }

    QString global_greeting(int type)
    {
        return qApp->translate("FriendlyConversation",
                               greeting_strings[type]);


Название: QObject::tr() и lupdate
Отправлено: bigirbis от Сентябрь 07, 2006, 08:32
Можно поступить по-тупому:
Код:

//Можно в мапу оформить, ну и вообще, дело вкуса...
QString str = QObject::tr( "some text" );
...
//Теперь осталось только достать уже транслированные строки
widget->setWindowTitle( str );


Название: QObject::tr() и lupdate
Отправлено: QCasper от Сентябрь 07, 2006, 09:18
Цитата: "DenKor"
Смысла в этом особого нет.
Обычно (я например) пишут в макросе английиский текст. А далее занимаюсь переводом.

Константы можешь использовать спомощью дериктивы define


а если у меня в коде в разных местах встречается (а иногда и в разных файлах) встречается "string", который мне нужно потом переделать в "the string"?

добавлено спустя 56 секунд:

 
Цитата: "bigirbis"
Можно поступить по-тупому:
Код:

//Можно в мапу оформить, ну и вообще, дело вкуса...
QString str = QObject::tr( "some text" );
...
//Теперь осталось только достать уже транслированные строки
widget->setWindowTitle( str );


пробовал. не работает. текст остается не переведенный.


Название: QObject::tr() и lupdate
Отправлено: bigirbis от Сентябрь 07, 2006, 09:50
Цитировать
пробовал. не работает. текст остается не переведенный.

Дело в том, что для такого подхода требуется сперва объявить данные переменые (например а пространстве имен), а потом инициализировать их в каком-нибудь методе (который, как правило, запускается в main).
Что вроде того:

Код:

namespace translate
{
QString str;

void init()
{
str = QObject::tr( "some text" );
}

};

int main()
{
...
QApplication app;
...
translate::init();
...
}


Название: QObject::tr() и lupdate
Отправлено: Вудруф от Сентябрь 07, 2006, 09:55
Цитировать
пробовал. не работает. текст остается не переведенный

Ты язык менял во время исполнения?


Название: QObject::tr() и lupdate
Отправлено: QCasper от Сентябрь 07, 2006, 10:06
Цитата: "Вудруф"
Цитировать
пробовал. не работает. текст остается не переведенный

Ты язык менял во время исполнения?


какой язык? вот отрывок кода:

Код:
QString c_text = QObject::tr("text");

QLabel *lbl = new QLabel(c_text);
QLabel *lbl1 = new QLabel(QObject::tr("string"));


первый лэйбл выдает "text", второй - "строка".
стоит заменить на:

Код:
QLabel *lbl = new QLabel(QObject::tr("text"));


он начинает выдавать "текст".


Название: QObject::tr() и lupdate
Отправлено: bigirbis от Сентябрь 07, 2006, 10:20
To QCasper
Почитай пост от Чт Сен 07, 2006 9:50 am - это реально работает(и уже давно).


Название: QObject::tr() и lupdate
Отправлено: Вудруф от Сентябрь 07, 2006, 13:09
Если это - глобальная константа:
Цитировать

QString c_text = QObject::tr("text");

То, может быть, она просто инициализируется до выполнения любого кода из main?

добавлено спустя 5 минут:

 А вопрос про смену языков в real-time был задан оттого, что собственно перевод осуществляется уже после подключения файла с переводом (извините за тавтологию). И при смене языка тебе придётся переводить заново все строки!
А подключение файла перевода происходит в main...
В общем, делай так, как написал bigirbis, и будет тебе счастье...


Название: QObject::tr() и lupdate
Отправлено: bigirbis от Сентябрь 07, 2006, 13:39
Если хочется круто-круто, то смотри книгу "C++ GUI Programming with Qt 4" главу "Part III: Advanced Qt/Chapter 17.  Internationalization/Dynamic Language Switching"
Книгу можно скачать в андеграунде.


Название: QObject::tr() и lupdate
Отправлено: itan от Сентябрь 08, 2006, 10:26
Я так понимаю, что если у меня есть группа классов (например, A,B и С), то реализуя текстовые сообщения, как A::tr("Text"), B::tr("Text") и С::tr("Text"), я в последующем могу добиться разного перевода слова "Text" в зависимости от используемого контекста (класса) ?
А что мне делать, если эта группа классов ни каким боком не наследует QObject (т.е. функция tr() в них не определена) ? Как добиться контекстозависимого перевода?


Название: QObject::tr() и lupdate
Отправлено: bigirbis от Сентябрь 08, 2006, 10:37
Можно попробовать вызвать
QString QObject::tr ( const char * sourceText, const char * comment )
и установить второй параметр, что-то вроде того:

Код:
class A
{
...
 QString tr( const char * sourceText ) { return QObject::tr( sourceText, "A" ); }
...
}


Название: QObject::tr() и lupdate
Отправлено: QCasper от Сентябрь 08, 2006, 13:54
Цитата: "bigirbis"
Можно попробовать вызвать
QString QObject::tr ( const char * sourceText, const char * comment )
и установить второй параметр, что-то вроде того:

Код:
class A
{
...
 QString tr( const char * sourceText ) { return QObject::tr( sourceText, "A" ); }
...
}


не помогает


Название: QObject::tr() и lupdate
Отправлено: itan от Сентябрь 08, 2006, 14:05
По идее, должно помочь вот это:
QString QCoreApplication::translate ( const char * context, const char * sourceText, const char * comment, Encoding encoding, int n )  [static]


Название: QObject::tr() и lupdate
Отправлено: QCasper от Сентябрь 08, 2006, 14:10
Цитата: "itan"
По идее, должно помочь вот это:
QString QCoreApplication::translate ( const char * context, const char * sourceText, const char * comment, Encoding encoding, int n )  [static]


ты сам пробовал?


Название: QObject::tr() и lupdate
Отправлено: itan от Сентябрь 08, 2006, 14:20
нет еще не пробывал, это всего лишь предположение


Название: QObject::tr() и lupdate
Отправлено: bigirbis от Сентябрь 08, 2006, 14:24
Нет, это все не пройдет. Надо внимательнее читать Assistant.
Вот работающий пример:
Код:
QString str = QT_TRANSLATE_NOOP( "class A", "A" );

Вот цитата из Assistant
Цитировать
const char * QT_TRANSLATE_NOOP ( const char * context, const char * sourceText )
Marks the string literal sourceText for dynamic translation in the given context, i.e the stored sourceText will not be altered. The context is typically a class. For example:
    static const char *greeting_strings[] = {
        QT_TRANSLATE_NOOP("FriendlyConversation", "Hello"),
        QT_TRANSLATE_NOOP("FriendlyConversation", "Goodbye")
    };

    QString FriendlyConversation::greeting(int type)
    {
        return tr(greeting_strings[type]);
    }

    QString global_greeting(int type)
    {
        return qApp->translate("FriendlyConversation",
                               greeting_strings[type]);
    }
The macro expands to sourceText.


Название: QObject::tr() и lupdate
Отправлено: noosooth от Сентябрь 08, 2006, 15:02
Цитата: "itan"
А что мне делать, если эта группа классов ни каким боком не наследует QObject (т.е. функция tr() в них не определена) ?


Посмотрите в Assistant макрос Q_DECLARE_TR_FUNCTIONS.
Он вроде как раз для Вашего случая.


Название: QObject::tr() и lupdate
Отправлено: QCasper от Сентябрь 08, 2006, 15:45
вот код

Код:
static const char *pluginName = QT_TRANSLATE_NOOP("PluginName", "TVChat");

extern "C" QString CSISPluginName() {
//return c_PluginName;
return qApp->translate("PluginName", pluginName);
}


- не переводит

эмм... забыл трансляторный файл инсталировать, теперь все работает:

Код:
extern "C" QString CSISPluginName() {
QTranslator myappTranslator;
myappTranslator.load(":translations/tvchat_ru.qm");
qApp->installTranslator(&myappTranslator);
//return c_PluginName;
return qApp->translate("PluginName", pluginName);
}


это мне в каждой функции подобного рода придется инсталить его?

добавлено спустя 18 минут:

 хех :) а почему, когда я пихаю

Код:
QTranslator myappTranslator;
myappTranslator.load(":translations/tvchat_ru.qm"); qApp->installTranslator(&myappTranslator);


в глобальную функцию, оно перестает работать? :) (в смысле не переводит)


Название: QObject::tr() и lupdate
Отправлено: bigirbis от Сентябрь 08, 2006, 15:52
Инсталлировать транслятор нужно только в main, приблизительно так:
Код:
QApplication a(argc, argv);

QTranslator translator;
translator.load(QString("applicationName_") + QLocale::system().name());
a.installTranslator(&translator);


Название: QObject::tr() и lupdate
Отправлено: QCasper от Сентябрь 08, 2006, 17:50
Цитата: "bigirbis"
Инсталлировать транслятор нужно только в main, приблизительно так:
Код:
QApplication a(argc, argv);

QTranslator translator;
translator.load(QString("applicationName_") + QLocale::system().name());
a.installTranslator(&translator);


ну во-первых не обязательно, а во-вторых, если у меня библиотечка, динамически подключаемая? где там мэйн?


Название: QObject::tr() и lupdate
Отправлено: Вячеслав от Сентябрь 08, 2006, 20:18
Цитата: "QCasper"
Цитата: "bigirbis"
Инсталлировать транслятор нужно только в main, приблизительно так:
Код:
QApplication a(argc, argv);

QTranslator translator;
translator.load(QString("applicationName_") + QLocale::system().name());
a.installTranslator(&translator);


ну во-первых не обязательно, а во-вторых, если у меня библиотечка, динамически подключаемая? где там мэйн?

Да все прекрасон работает и без майна ;)
Кусок одной из первых поделок на QT было написано для тренеровки - 4 осваивал ...
Код:

bool ClockPlugin::initPlugin(QMainWindow *parent,void* session,QString& intName)
{
_mParent=parent;
QCoreApplication* app=QCoreApplication::instance();

QString locale = QLocale::system().name();
translator=new QTranslator;

if (translator->load(QString("df_iClock_") + locale))
app->installTranslator(translator);

это иницализация плагина - код был содран из assistanta в лоб и заработал ;)


Название: QObject::tr() и lupdate
Отправлено: bigirbis от Сентябрь 09, 2006, 13:41
Цитировать
Инсталлировать транслятор нужно только в main

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