Tr member function of QObject takes only char * as input parameter
-
tr member function of QObject takes only char * as in parameter. Thus if you have multibyte characters(eg japanese characters) in a QString, and if you need to use tr, then this QString needs to be first converted to char * using ascii(). But this result in loss of data since char * can not hold multibyte string.
Actual problem is that, in a huge code, it is difficult to keep a track if the the string is already translated or not. so we end up putting tr function at lot many places. for the tr function, it needs a char * as input parameter. thus, suppose if we have a Qstring which has been already translated to some multibyte characters, then using ascii() function on this QString to get char *, which is an input parameter to tr function, will make it lose all the data.
-
You can tell Qt about the encoding of the source file.
However, what I do personally, is keep everything in English in the source files, and only then translate to my actual target language. That makes my life much easier, as I never have to deal with encoding issues. Notice that the encoding your editor uses is also a factor here. That all goes away as soon as you just use English (no characters outside of the standard ASCII set needed) in your sources. Encoding of your translated strings is all handled nicely by default. You can compile in your translation file by putting the translation file in a resource, and loading it from there in your main function.
-
Even we have all the translation in the resource file. the content of source file is all in english. but my problem is, once I get the translated string using QObject::tr(const char *, const char *), if I use QString::ascii(), I get a char * in return. Thus if the translated characters are multibyte, then the output of QString::ascii() will be garbage.
Reason for calling QString::ascii() is that, i can not keep a track of whether the string has been translated. hence I tend to call QObject::tr(const char *, const char *), multiple times, and since this function takes char *, I need to use QString::ascii().To sum up
Untranslated QString --> tr() --> translated QString (multibyte) ----> ascii() ----> Garbage characters ----> tr() ----->Garbage characters -
[quote author="vivek.narvekar" date="1313568937"]tr member function of QObject takes only char * as in parameter. Thus if you have multibyte characters(eg japanese characters) in a QString, and if you need to use tr, then this QString needs to be first converted to char * using ascii(). But this result in loss of data since char * can not hold multibyte string.[/quote]
Your analysis is slightly incorrect: QTextCodec::codecForTr is used to decode the byte sequence, not fromAscii().
Btw, you can perfectly put string literals with Japanese characters in your source code. It's all up to the encoding of it. For instance, you can save the source file as UTF-8 and then use trUtf8 (or set UTF-8 as the text codec for tr). -
So, it seems the solution is to clean up your design. I really don't see a good reason to try to re-translate an already translated string. Calling tr() on non-fixed strings is not going to work anyway, as:
the qupdate application will not find the actual string to translate, and
the string you put into the tr() function will most likely not be in the translation file.
In short:
@
//do this
QLabel* l = new QLabel(tr("My cool label"), this);//and do NOT do this
char* inputText;
//assign something to inputText;
QLabel* l = new QLabel(tr(inputText), this);
@ -
Thanks a lot Andre and Peppe for responding so quickly.
Its not possible to follow the example which you given Andre, because the application on which I am working is huge one, and the string moves through lot many layers before actually reaching QT layer.
Well actually, I dont want the string to be translated twice. As you rightly said Andre, in point 2.
In fact during a second tr call, I want the string to remain as it is. Second call to tr is not a desired one, but actually a forced one, due to complex structure of the existing code. more complexity is because, its not only about setting the text to widget, but also getting it back and comparing it. -
If the string comes from other, deeper, non-Qt layers of your application, then those layers need to take care of the proper translation. You should not call tr() on non-fixed strings, ever.
If you want, you could set up some kind of translation map of your own in your GUI layer, where you setup a map of messages and their translated counterparts. That only works for fixed messages, of course:
@
//let m_translationMap be a QMap<QString, QString>void initTranslationsMap()
{
m_translationMap.insert("error in module fooBar", tr("error in module fooBar"));
// many more messages would follow
}void getTranslation(const QString& untranslatedText)
{
return m_translationMap.value(untranslatedText, untranslatedText);
}
@ -
[quote author="vivek.narvekar" date="1313575846"]Thanks a lot Andre and Peppe for responding so quickly.
Its not possible to follow the example which you given Andre, because the application on which I am working is huge one, and the string moves through lot many layers before actually reaching QT layer.[/quote]
You can STILL translate them using QCoreApplication::translate, but you need to mark the literals so lupdate finds them, or either build a convoluted solution based on QTranslator...
[quote]
Well actually, I dont want the string to be translated twice. As you rightly said Andre, in point 2.
In fact during a second tr call, I want the string to remain as it is. Second call to tr is not a desired one, but actually a forced one, due to complex structure of the existing code. more complexity is because, its not only about setting the text to widget, but also getting it back and comparing it.
[/quote]I've never seen an usecase for getting back, from the GUI, the translated user-visible strings. What's yours?
-
@Andre -
I will try to see if I can follow the structure which you have suggested.
I totally agree with you, that tr() should not be used on non-fixed string. But, its very difficult to incorporate this in our application, since the code is very huge, more than 15 years of development work.@Peppe -
QComboBox::currentText() , etc, which will return translated text, have been used in the application. the returned text is used for string comparison@both -
Thanks a lot for valuable info -
[quote author="vivek.narvekar" date="1313578838"]@Peppe -
QComboBox::currentText() , etc, which will return translated text, have been used in the application. the returned text is used for string comparison
[/quote]Can't you use the currentIndex() instead? Or set the untranslated string as additional itemData?
-
"untranslated string as additional itemData" seems to be better option. i will give it a try.
Thanks