PDA

View Full Version : Qt translation



jbarrena
31st March 2015, 15:23
Hi there,

I am trying to translate some text read from a file. I have 25 text that are translated in linguist, and some text is read from files. In case that the read strings have translations available, I would like to translate them. Is there any way to achieve that??

Thanks in advance!

yeye_olive
31st March 2015, 16:24
Sure, install the QTranslator into the application and call QObject::tr() to translate strings.

jbarrena
31st March 2015, 16:52
Hi yeye_olive,

I am installing a translator, and using tr to translate the strings, but how can I introduce the translateable strings into the ts files?

Thanks!!

stampede
31st March 2015, 17:01
Use Qt Linguist.

jbarrena
31st March 2015, 17:04
Yes, but QT linguist only detects translatable strings in the project, but where do I have to introduce these texts??

stampede
31st March 2015, 17:29
Sorry I didn't read the whole thread :o
You can use macro "QT_TRANSLATE_NOOP" in any text file and have it parsed for translation by lupdate, it is enough to add the file to the list of "headers" in the .pro file, for example:


// file: test.txt
this is an example of QT_TRANSLATE_NOOP("TextFile","text to translate")



// project.pro
...
HEADERS += test.txt

String "text to translate" will now be available for translation after running lupdate.
In the app code you can use it after translation:


QString test = qApp->translate( "TextFile", "text to translate" );

jbarrena
7th April 2015, 14:40
Thank you for the reply!! It really helped me!!

But, now I am trying to translate a text containing º character. I se that I can only pass char parameters to qApp->translate function, an I can see inside this function that text passed is "Temperature is shown in ºC" instead of "Temperature is shown in ºC", and it is unable to find the text to be translated.

How can I pass the correct string to qApp->translate in order to have º containing string translated??

Thanks again!

anda_skoa
7th April 2015, 15:19
Is your source file encoded in UTF-8?

Cheers,
_

jbarrena
7th April 2015, 15:32
Yes, my text editor option for file encoding is set in UTF-8

anda_skoa
8th April 2015, 08:52
Then it should be possible to have the target character as part of a C string literal.

Cheers,
_

jbarrena
8th April 2015, 09:56
Yes, but how is it possible to send a string containing a º character to qApp->translate() function if we only have char* parameter on it??

yeye_olive
8th April 2015, 10:13
Yes, but how is it possible to send a string containing a º character to qApp->translate() function if we only have char* parameter on it??
Like this:


QCoreApplication::translate("My context", "My translatable UTF-8 string containing all kinds of characters like º");

Your source files must be encoded in UTF-8.

jbarrena
8th April 2015, 10:27
And what if we read the string with º charcter from a file to a QString? What type of conversion do I need to do??

Thanks again!

yeye_olive
8th April 2015, 10:52
First things first: what version of Qt are you using? Qt 4 lets you choose with which codec tr() and translate() interpret the char * strings they receive (see QTextCodec::codecForTr(), by default Latin-1), while Qt 5 always assumes these strings to be encoded in UTF-8. Even if you use Qt 4, it may be a good idea to switch to UTF-8 to ease porting to future versions of Qt.

Now, if you read these strings from a file, I can see two situations:

if the strings are encoded in UTF-8 and null-terminated in the file: do not bother going through QString, just load the plain bytes from the file and pass a pointer to the first character of the string to QCoreApplication::translate();
if the file uses another kind of representation for the strings: load them into QString if that makes sense, then retrieve the null-terminated UTF-8 representation with QString::toUtf8(), and pass a pointer to the first byte to QCoreApplication::translate().

jbarrena
8th April 2015, 14:58
Hi,

I managed to get translated the text read from an XML file containing º character. I discover that the text read from the file contains the charcter  (0xc2) before the º (0xba), so if I remove the c2 character from the QByteArray, I obtain the UTF encoded string (with its '\000' terminating character included). Does anybody know why is this happening??

Thanks for the attention!

yeye_olive
8th April 2015, 15:21
The character 'º':

has Unicode code point U+00ba;
is encoded in UTF-8 by the sequence of two bytes 0xc2 0xba.

Do not confuse those two things. If your XML file is encoded in UTF-8, then an hexadecimal editor will show the sequence 0xc2 0xba somewhere in the file, but an XML parser outputting QStrings will represent 'º' as a single QChar with code point U+00ba.

jbarrena
9th April 2015, 07:58
The character 'º':

has Unicode code point U+00ba;
is encoded in UTF-8 by the sequence of two bytes 0xc2 0xba.

Do not confuse those two things. If your XML file is encoded in UTF-8, then an hexadecimal editor will show the sequence 0xc2 0xba somewhere in the file, but an XML parser outputting QStrings will represent 'º' as a single QChar with code point U+00ba.

My XML file is encoded in UTF-8, the header is <?xml version="1.0" encoding="UTF-8"?> and the output QByteArray (QXmlStreamAttributes.value("xxx").toUtf8()) contains "{68 'D', 69 'E', 76 'L', 73 'I', 67 'C', 65 'A', 84 'T', 69 'E', 32 ' ', 52 '4', 48 '0', -62 'Â', -70 'º', 67 'C'}" to represent "DELICATE 40ºC".

Am I losing something?

Thanks again!

yeye_olive
9th April 2015, 10:44
Am I losing something?

Yes. You keep confusing characters and bytes. The good old Latin-1 encoding encodes each character on 1 byte. The debugging output:


"{68 'D', 69 'E', 76 'L', 73 'I', 67 'C', 65 'A', 84 'T', 69 'E', 32 ' ', 52 '4', 48 '0', -62 'Â', -70 'º', 67 'C'}"

just means "this is a QByteArray, whose bytes are [0x44, 0x45, 0x4C, 0x49, 0x43, 0x41, 0x54, 0x45, 0x20, 0x34, 0x30, 0xC2, 0xBA, 0x43]; for your (in)convenience, I chose to print the value of each byte as a signed 8-bit integer, followed by the corresponding Latin-1 character, in case this byte sequence is supposed to represent a text encoded in Latin-1."

Your QByteArray does represent an encoding of the text "DELICATE 40ºC"... just not in Latin-1, but in UTF-8, as the call to toUtf8() implies. UTF-8 is a variable-length encoding, which means that the number of bytes it takes to encode an individual character is not the same for every character. In addition, UTF-8 was designed so that ASCII characters such as 'D', 'E', 'L', 'I', 'C', 'A', 'T', ' ', '4', and '0' are encoded on exactly one byte, actually the same byte as for Latin-1. By contrast, 'º' is encoded as the single byte 0xBA in Latin-1, and the 2-byte sequence 0xC2 0xBA in UTF-8. The fact that the byte 0xBA appears in both encodings is a coincidence. This is probably the source of your misunderstanding.

In summary, the byte sequence you get by calling toUtf8() is correct, and you can pass it to tr() if you are using Qt 5, or if you are using Qt 4 and QTextCodec::codecForTr() is UTF-8.

By the way, the character you use, 'º' (Unicode code point U+00ba, UTF-8 encoding 0xc2 0xba) is probably not the one you want to mean "degrees". The correct one is '°' (Unicode code point U+00b0, UTF-8 encoding 0xc2 0xb0).

jbarrena
16th April 2015, 15:56
Hi,

I am not totally able to manage it. I have the files in UTF-8, and QTextCodec::setCodecForTr(QTextCodec::codecForName ("UTF-8")); set. I am sending QString.toUtf8() to qApp->translate() function, but I am still reading "DELICATE 40ºC" inseide QCoreApplication::translate() function. And it doesn´t translate the text.

I am a bit lost... :(

Thanks nevertheless!!!

I forgot it,

If I send toLatin1() instead of toUtf8---89 translation is done correctly.

yeye_olive
16th April 2015, 17:09
So, you are using Qt 4. That is good to know.


I am still reading "DELICATE 40ºC" inseide QCoreApplication::translate() function.
What does it mean? What do you read and how? The const char *sourceText parameter of QCoreApplication::translate() should point to a NULL-terminated UTF-8 encoding of the Unicode string "DELICATE 40ºC". Are you absolutely certain that whatever displays it to you interprets it in this way? As illustrated in my previous post, a pretty-printer may decide to interpret the const char * as a pointer to a NULL-terminated string encoded in Latin-1.


If I send toLatin1() instead of toUtf8---89 translation is done correctly.
Here is what I believe is likely happening. Your code is now correct, but lupdate interpreted your source files as if they were encoded in Latin-1 rather than UTF-8 and ended up picking the wrong strings for translation. You can confirm this by loading the generated ts files in Qt Linguist. Does it ask you to translate "DELICATE 40ºC" or "DELICATE 40ºC"? In the second case, it means that the UTF-8-encoded string literals in your sources were decoded by lupdate in Latin-1. In that case, the fix should be simple; just add the line

CODECFORTR = UTF-8
to your .pro file, re-run lupdate, provide the translations, and re-run lrelease.

If this does not solve your problem, please post an archive with a minimal, complete, and compilable example reproducing the problem.