Qt-interest Archive, January 2007
Correct place for translation files
Message 1 in thread
In a Qt-based program we are developing [0], we are currently putting
the translation files (.ts and .qm) in /qt/ts/, while the source code
is at /src/ .
In main.cpp we have:
// Translations for QAntenna
QTranslator myappTranslator;
myappTranslator.load("qantenna_" + locale,"qt/ts");
app.installTranslator(&myappTranslator);
Now, a maintainer for the program has wrote us:
"For the next revision, qantenna needs a 'make install' target.
I noticed that qantenna looks for the translated files in the
"qt/ts" directory.
This is also important for people who create a Debian or rpm
package, because they want to inlude the translated files
in the package... :-)"
Now, (not knowing where to start) I searched through qmake's doc, but
I couldn't find a clue of which possibilities we have to do something
in order to solve this.
If you have any clue (RTFMs whith a link are also much welcomed), I
would please ask you to tell me :-)
Regards, Lisandro
[0] http://sourceforge.net/projects/qantenna
--
[ signature omitted ]
Message 2 in thread
Lisandro Damián Nicanor Pérez Meyer schrieb:
> In a Qt-based program we are developing [0], we are currently putting
> the translation files (.ts and .qm) in /qt/ts/, while the source code
> is at /src/ .
> ...
> "For the next revision, qantenna needs a 'make install' target.
> I noticed that qantenna looks for the translated files in the
> "qt/ts" directory.
> ...
> Now, (not knowing where to start) I searched through qmake's doc, but
> I couldn't find a clue of which possibilities we have to do something
> in order to solve this.
The problem you're facing has nothing to do with qmake (in other words:
qmake won't help you here in this case).
The problem is you have to install the *.qm files somewhere along with
your executables. This "somewhere" place has to be known to your
application, off course.
Our application for example places them in
<application dir>/i18n/*.qm
(that is, in the application subfolder 'i18n').
Off course when loading these *.qm files at runtime the path has to be
specified, in our case it is simply:
QCoreApplication::applicationDirPath() + "/i18n"
in your case it is "qt/ts" (note: this relies on the fact that the
current working directory must be the application directory which might
fail!).
As to summarize: there is no "correct" place where to put your *.qm
files! You (or the packager of the Linux distro) might want to put them
under "/usr/local/share/antenna/translation" or wherever. In any case
this path must be known at runtime to your application!
So you either
- assume a fixed path and hard-code it into your application
(a subfolder of your application directory comes handy here, except
when you really want to install the executables under /usr/local/bin
or /usr/bin, as most Linux distros prefer to do so)
- use QSetttings and store the path in the application settings, so
the application packager is free to put the *.qm wherever she wants
to, e.g. /usr/local/share/antenna/translations
(as long as she modifies and installs the application settings file
correctly)
qmake itself can't take this decision for you, as I said. But you can
define "install targets" with qmake, so when you enter 'make install'
the necessary application files (and *.qm files) are copied to the place
of your choice.
--
[ signature omitted ]
Message 3 in thread
> - assume a fixed path and hard-code it into your application
> (a subfolder of your application directory comes handy here, except
> when you really want to install the executables under /usr/local/bin
> or /usr/bin, as most Linux distros prefer to do so)
>
> - use QSetttings and store the path in the application settings, so
> the application packager is free to put the *.qm wherever she wants
> to, e.g. /usr/local/share/antenna/translations
> (as long as she modifies and installs the application settings file
> correctly)
Or you include it in a Qt ressource file and never worry about the path
and correct deployment. Works for me so far.
--8><--
QTranslator* t = new QTranslator(qApp);
t->load(":/translations/qt_de");
qApp->installTranslator(t);
--><8--
Martin
--
[ signature omitted ]
Message 4 in thread
Martin Gebert schrieb:
>> - assume a fixed path and hard-code it into your application
>> ...
>> - use QSetttings and store the path in the application settings, so
>> ...
> Or you include it in a Qt ressource file and never worry about the path
> and correct deployment. Works for me so far.
That's another good solution :) But one needs to be aware that you limit
the available translations to the ones compiled into the resource file.
This might not be that bad if you are the only one doing translations,
but the OP explicitly wrote:
myappTranslator.load("qantenna_" + locale,"qt/ts");
that is, the name of the translation is constructed dynamically
(depending on the current locale of the system).
Like this one can put additional translations into this <app_dir>/qt/ts
folder later on and they are picked up the next time the application
starts (without recompilinig anything).
This is not possible with resource files: you need to re-compile the
resource files each time a new translation becomes available.
Cheers, Oliver
--
[ signature omitted ]
Message 5 in thread
Lisandro Damián Nicanor Pérez Meyer wrote:
> In a Qt-based program we are developing [0], we are currently putting
> the translation files (.ts and .qm) in /qt/ts/, while the source code
> is at /src/ .
> In main.cpp we have:
>
> // Translations for QAntenna
> QTranslator myappTranslator;
> myappTranslator.load("qantenna_" + locale,"qt/ts");
> app.installTranslator(&myappTranslator);
One alternative is to put the translations in the application's resources
like the i18n example:
http://doc.trolltech.com/4.2/tools-i18n.html
Then you can load them using resource paths:
http://doc.trolltech.com/4.2/resources.html
However, I can understand if maintainers would prefer to distribute a
separate package for each translation.
> Now, a maintainer for the program has wrote us:
>
> "For the next revision, qantenna needs a 'make install' target.
> I noticed that qantenna looks for the translated files in the
> "qt/ts" directory.
>
> This is also important for people who create a Debian or rpm
> package, because they want to inlude the translated files
> in the package... :-)"
Since different distributions may put translations in different places,
it may be helpful to make the path to the directory containing the
translation files configurable from the build process.
> Now, (not knowing where to start) I searched through qmake's doc, but
> I couldn't find a clue of which possibilities we have to do something
> in order to solve this.
If you want to define a path in the build process and use it in the source
code, you may want to use the qmake DEFINES variable:
http://doc.trolltech.com/4.2/qmake-variable-reference.html#defines
I'm not sure if this approach is helpful to package maintainers or whether
they prefer other ways of changing the application's behavior to suit their
target platforms.
> If you have any clue (RTFMs whith a link are also much welcomed), I
> would please ask you to tell me :-)
The other suggestions in this thread also sound reasonable. I'd like to see
an example of a pure Qt application with translations that's packaged by a
Linux distribution. Looking at source packages for distributions would give
you an idea of the "best practice" and might also inspire us to update the
documentation:
http://doc.trolltech.com/4.2/deployment-x11.html
> [0] http://sourceforge.net/projects/qantenna
Looks like an interesting application!
David
--
[ signature omitted ]
Message 6 in thread
2007/1/18, David Boddie <dboddie@xxxxxxxxxxxxx>:
[snip]
> The other suggestions in this thread also sound reasonable. I'd like to see
> an example of a pure Qt application with translations that's packaged by a
> Linux distribution. Looking at source packages for distributions would give
> you an idea of the "best practice" and might also inspire us to update the
> documentation:
>
> http://doc.trolltech.com/4.2/deployment-x11.html
OK, Joop Stakenborg, Debian's maintainer of QAntenna, has done a good research:
2007/1/21, Joop Stakenborg <pg4i @ xs4all.nl>:
> On Sat, 20 Jan 2007 14:35:52 -0300
> "Lisandro Damián Nicanor Pérez Meyer" <perezmeyer@xxxxxxxxx> wrote:
>
> > I have asked at Qt-interest mailing list[0], and here's a resume of
> > the possible solutions we can take:
[snip solutions that you all gave me in this thread]
> Well, on Debian there are several applications which are pure Qt.
> I have taken a look at vipec: http://vipec.sourceforge.net/
>
> Here is how they do it:
> src/main.cpp contains a function for loading tanslation files, please
> note the instance "vipecHome":
> --------------------------------------
> const QString& languageFile = Setup::instance()->languageFile();
> QTranslator* translator = new QTranslator(0);
> if (!languageFile.isEmpty())
> {
> const QString& vipecHome = Setup::instance()->vipecHome();
> QString dirName = vipecHome + "/messages";
> Logger::debug("Looking for " + languageFile + " in directory" + dirName);
> QTranslator* translator = new QTranslator(0);
> translator->load( languageFile, dirName );
> app.installTranslator( translator );
> }
> app.installTranslator( translator );
> ----------------------------------------
> In src/setup.cpp vipecHome is defined:
> ----------------------------------------
> QDir dir;
> vipecHome_ = QString(getenv("VIPECHOME"));
> if ( vipecHome_.isEmpty() )
> {
> #ifdef VIPECHOME
> vipecHome_ = QString(VIPECHOME);
> if (vipecHome_.isEmpty())
> {
> vipecHome_ = dir.absPath();
> Logger::warning("VIPECHOME not set, assuming " + vipecHome_);
> }
> #else
> vipecHome_ = dir.absPath();
> Logger::warning("VIPECHOME not set, assuming " + vipecHome_);
> #endif
> }
> ----------------------------------------
> This is very elegant, we can set the path to qantenna data in several
> ways, if we do it like this. However, we must add VIPECHOME to src/vipec.pro:
> ----------------------------------------
> DEFINES = QT_FATAL_ASSERT VIPECHOME=\"$(VIPECHOME)\"
> ----------------------------------------
> This way a package maintainer can do thinks like:
> $(MAKE) VIPECHOME=/usr/share/vipec
>
> Regards,
> Joop
As you can see, it seems a very good approach.
Regards, and thank you all for your help, Lisandro.
--
[ signature omitted ]