How to use pyside6-lupdate?
-
Hi!
I'm working on an small PySide6 project. I upgraded to 6.2.0 this morning in order to use i18n tools. But I can't find a way to uselupdate
...First attempt
I triedpyside6-lupdate atb.pro
withatb.pro
being:SOURCES = atb/main.py FORMS = ui/main_window.ui TRANSLATIONS = ui/i18n/atb_fr.ts
It spawns a weird utf8 error :
File "[...]lib\site-packages\PySide6\scripts\pyside_tool.py", line 72, in qt_tool_wrapper msg = err.decode("utf-8") UnicodeDecodeError: 'utf-8' codec can't decode byte 0x8a in position 15: invalid start byte
I commented out this
.decode("utf-8")
and found that it concealed a real error message: something like "the specified path does not exist" (translated from french), but I double-checked every pathes.Second try
With no project file, I tried to put everything on the command line. I got no errors but no .ts file were created...$ pyside6-lupdate -extensions py,ui ui/ atb/ -ts ui/i18n/atb_fr.ts Scanning directory 'ui/'... Scanning directory 'atb/'... $ ls -l ui/i18n/ total 0
Third try
Looking for my .ts file, I stumbled upon the linguist example inlib/site-packages/PySide6/examples/widgets/linguist/
and I tried to follow it.
I made a similar .pyproject file:{ "files": ["atb/main.py", "ui/main_window.ui", "ui/i18n/atb_fr.ts"] }
But:
$ pyside6-lupdate -project atb.pyproject Error: lupdate error: Missing keys in project description: projectFile.
I'm feel a bit lost... how should I set up i18n for PySide6?
Dev environment : Windows 10, Python 3.7.4, PySide 6.2.0 installed in a virtual env
Thanks for your help!
-
@gbassiere, I'm not very experienced with i18n in Qt but I use it in my project so probably I may help you here.
First of all - the most recent version oflupdate
says that pro-files usage will be deprecated. So, keep it in mind trying your and my examples.I created my pro-file some time ago so don't remember all details but I have only SOURCES and TRANSLATIONS there. I don't use FORMS as ui-files are converted into python code with help of
uic
. If you load them directly from your code - probably it is required.Then I run
lupdate -no-obsolete file.pro
now, without extra options, it creates ts-files based on py-files list provided in SOURCES.
So, your "First attemt" looks most correct for me.And just one more thought - as you are on Windows and have this error
"UnicodeDecodeError: 'utf-8' codec can't decode byte 0x8a in position 15: invalid start byte"
- I suspect thatlupdate
may expect that your py-files will use UTF-8 encoding. But most probably Windows saves them in your French code page (probably cp1252) -
Hi @StarterKit, thanks for your help!
I've retried with .pro file using
-no-obsolete
option and removing FORMS entry inatb.pro
. But it doesn't solve the problem. I get the same error.Thanks for the tip about compiled ui files. I agree with you, there's no need of translating .ui files since their compiled Pyhton version will be translated.
Can you confirm that pathes in .pro files are unix-style (I mean with regular '/') and relative to the .pro file? From the docs, I believe most people generate the .pro file with QMake but I don't have this command since I'm in a PySide environment (rather than regular Qt). The documentation is unfortunately very poor about writing this file manually.
By the way, you seem to use
lupdate
command, how did you get it? If I install PySide6 in a fresh virtual environment, I just getpyside6-lupdate
... Did you tweak your$PATH
to includelib/site-packages/PySide6
?Regarding Unicode, you're right about Windows but I develop under PyCharm IDE which makes up for Windows flaws, it is configured to always use utf-8.
But the unicode problem is not in my files, the Python exception is thown in
qt_tool_wrapper()
inPySide6/scripts/pyside_tool.py
, line 72:msg = err.decode("utf-8")
Here,
err
is the error message returned by the subprocess which actually runlupdate
. If I comment out.decode("utf-8")
, I can see that it is a Windows error message:$ pyside6-lupdate.exe -no-obsolete atb.pro Error: b"Le chemin d'acc\x8as sp\x82cifi\x82 est introuvable.\r\n" while executing '[...]lib\site-packages\PySide6\lupdate -no-obsolete atb.pro'
The error message is in french (since it is my OS language), it translates to something like "the specified path does not exist" or "the system cannot find the specified path". But I'm sure that the path exists!
-
Hi @gbassiere
I think different nameslupdate
andpyside6-lupdate
are simply because different operational systems. I.e. yourpyside6-lupdate
looks completely fine for me. I saw this kind of name difference before and it didn't have impact.On my windows machine I also have
pyside6-lupdate
. I checked it from command line and it works:h:\projects\test_i18n>c:\<full_path>\Python38\Scripts\pyside6-lupdate.exe main.py -ts fr.ts Updating 'fr.ts'... Found 1 source text(s) (1 new and 0 already existing) h:\projects\test_i18n>
I got
fr.ts
file generated. With pro-file I also gotError: The system cannot find the path specified.
I checked different options - full path, short path, quoted names, with/
and\
path separators... I have no idea what is wrong but I confirm - it raises path not found error on Windows while I have no such problems on Linux with the same or very similar pro-file. -
OK, I finally managed to have a satisfactory behaviour for UI files :
$ pyside6-lupdate.exe -recursive -extensions ui ui/ -ts ui/i18n/atb_fr.ts Scanning directory 'ui/'... Updating 'ui/i18n/atb_fr.ts'... Found 13 source text(s) (13 new and 0 already existing)
It works as well without the
-extensions ui
parameter. Fine.For Python files, it is bit more complicated.
Parameter
-recursive
doesn't seem to work. I believe files are found but.translate()
is not recognized in it.$ pyside6-lupdate.exe -recursive atb/ -ts ui/i18n/atb_fr.ts Scanning directory 'atb/'... Updating 'ui/i18n/atb_fr.ts'... Found 0 source text(s) (0 new and 0 already existing)
With explicit
-extensions
parameter, my Python files do not even seem to be found$ pyside6-lupdate.exe -recursive -extensions py atb/ -ts ui/i18n/atb_fr.ts Scanning directory 'atb/'...
But if I directly point to a Python file with message to be translated, it works
$ pyside6-lupdate.exe atb/views/main_window.py -ts ui/i18n/atb_fr.ts Updating 'ui/i18n/atb_fr.ts'... Found 2 source text(s) (2 new and 0 already existing)
I can always resort to good old
find
command but it's a bit cumbersome:$ find atb/ -name \*.py -exec pyside6-lupdate.exe '{}' -ts ui/i18n/atb_fr.ts \; Updating 'ui/i18n/atb_fr.ts'... Found 0 source text(s) (0 new and 0 already existing) Updating 'ui/i18n/atb_fr.ts'... Found 0 source text(s) (0 new and 0 already existing) Updating 'ui/i18n/atb_fr.ts'... Found 2 source text(s) (2 new and 0 already existing) Updating 'ui/i18n/atb_fr.ts'... Found 0 source text(s) (0 new and 0 already existing) [...]
-
I also notice that
lupdate
is picky about what is actually a string to be translated. Examples below:# This will be detected by `lupdate` self.tr("Lorem ipsum...") # also this: QCoreApplication.translate("MainWindow", "Lorem ipsum...") # but neither this: QCoreApplication.translate("MainWindow", b"Lorem ipsum...") # nor this: QCoreApplication.translate("MainWindow", u"Lorem ipsum...")
The funny thing is that
uic
generate the latter form (which obsolete but remain supported, PEP414). Fortunately, I can get collect translation from the UI file. -
@gbassiere yes,
uic
generatesu"string"
, but apparently mylupdate
works fine with them as my UI is translated... -
for anyone else who still having this problem, it seems lupdate tool is working well in PyQt5 to translate .pro to .ts. So if you could do it, one workable way is to create another PyQt5 environment and use "pylupdate5 XXX.pro" to get the ts file. Than you can back to your PySide6 environment to do the rest part.
-
A tutorial can be found at https://doc.qt.io/qtforpython-6/tutorials/basictutorial/translations.html .