Localization of a library



  • Hi all,

    I put common functions in a dynamical linked library for my main app. The strings and forms of main app are translated and will be loaded with QTranslator::load(...) and installed with QApplication::installTranslator(...), it works. But the translated strings and forms in the lib are not used, always english only! App and lib translation loading and installing are the same:

    @
    QTranslator translator;
    translator.load("german.qm");

    QApplication::installTranslator(&translator);
    @

    Why are the strings and forms from lib in english only? Any hints?

    Thanks!
    Chris



  • Does german.qm really contain the translations for the library too?



  • Yes, I know, that is strange! I have test it with full path to german.qm ... all strings and forms are the english ones! I cannot explain this!



  • Some suggestions:

    • Make sure that your translation file is loaded successfully. Try:
      @qDebug()<<translator.load("german.qm");@
    • Make sure you're loading language file before instantiating GUI elements.


  • As you make the translator a local stack object, where do you call this?
    When the method exits, the translator will be destroyed and uninstalled.



  • [quote author="soroush" date="1338288047"]* Make sure that your translation file is loaded successfully. Try:
    @qDebug()<<translator.load("german.qm");@[/quote]

    I made this already, it's always true!

    [quote author="soroush" date="1338288047"]* Make sure you're loading language file before instantiating GUI elements.[/quote]

    I load and install all translations in the main function before the MainWindow will initialized, but the lib has no main function!? Where can I load and install translations for the lib?



  • A library is a passive object. It has no entry point. So you may need to call a function of your library that installs translator, from program that uses the library.



  • Yes, I made this. In my MainApp:

    @
    int main(int argc, char *argv[]) {
    QApplication application(argc, argv);

    QTranslator qtTranslator, appTranslator;
    QTextCodec::setCodecForTr(QTextCodec::codecForName("utf8"));
    
    qtTranslator.load("/home/chris/myApp/locale/qt_de.qm");
    appTranslator.load("/home/chris/myApp/locale/german.qm");
    
    application.installTranslator(&qtTranslator);
    application.installTranslator(&appTranslator);
    
    MyLib::loadTranslation();
    
    MyApp myApp;
    myApp.show();
    
    return application.exec&#40;&#41;;
    

    }
    @

    MyLib:

    @
    void MyLib::loadTranslation() {
    QTranslator translator;
    QTextCodec::setCodecForTr(QTextCodec::codecForName("utf8"));

    translator.load("/home/chris/myLib/locale/german.qm");
    
    QApplication::installTranslator(&translator);
    

    }
    @



  • All

    @QTranslator::load(...)@

    functions returns true and all strings/forms of MyApp are translated, but all strings/forms of MyLib are english only!

    I don't know why!



  • Sorry I didn't noticed that... calling
    @
    QApplication::installTranslator(&translator);
    @
    inside a library makes no sense. There should be one instance of QApplication that installs all translation.

    Consider Qt itself. When you load & install a translation of Qt libraries, there is no need to call any member inside libraries.

    Make sure that your classes are inherited from QObject. They should also implement signal/slot mechanism (use Q_OBJECT macro).

    I wrote a simple test. Works fine for me.



  • I should also mention that, If you're re-implementing changeEvent(QEvent *e) and you tend to use texts from library in your GUI, you will have two sources for translation. This will prevent your application from extracting text correctly.



  • The german.qm is compiled in the lib as resource. The hard coded path above was a test. How can I load german.qm from library resource to load & install the translation? Is there a way?



  • Hmmm
    You're doing it from hard way!
    Ask your library to give you binary data of her translation file (contents of .qm embedded in your library).
    Create a QTranslator in your application. "Load your binary data":http://doc-snapshot.qt-project.org/4.8/qtranslator.html#load-3:
    @translator.load ( const uchar * data, int len)@
    Install your translator to QApplication (outside library)



  • Still a little problem: The data of german.qm from lib resource is compressed, so I need to use

    @QByteArray qUncompress(const uchar *data, int nbytes)@

    But how do I get a const uchar* from the QByteArray for QTranslator::load?



  • It should be possible to load the translation directly from the ressource:

    @
    QTranslator trans;
    trans.load(":/path/to/resource/german.qm");
    @



  • @
    QByteArray ba;
    ba = ...
    unsigned char data = (unsigned char) ba.data();
    @

    Volker's solution is better.



  • [quote author="realdarkman" date="1338289960"]MyLib:

    @
    void MyLib::loadTranslation() {
    QTranslator translator;
    QTextCodec::setCodecForTr(QTextCodec::codecForName("utf8"));

    translator.load("/home/chris/myLib/locale/german.qm");
    
    QApplication::installTranslator(&translator);
    

    }
    @
    [/quote]

    As written earlier, you destroy the translator object after installing it directly. This will lead to no loaded translation again. You have to create it on the heap or create it in main and give it to the function.



  • The german.qm is a ressource of MyLib, Volker's solution will not work!? Or can I access the MyLib resources from MyApp?

    Is there a better (C++) method to cast the ba.data()? I want to avoid C casts!



  • Volkers solution should work if you don't destroy the translator object.



  • [quote author="Gerolf" date="1338366133"]You have to create it on the heap or create it in main and give it to the function.[/quote]

    Create on heap? I give the translator to loadTranslation, but it doesn't work:

    [quote]/usr/include/QtCore/qtranslator.h:94: error: 'QTranslator::QTranslator(const QTranslator&)' is private[/quote]



  • What is the path from MyApp to MyLip german.qm?

    @
    libTranslator.load(":/locale/german.qm")
    libTranslator.load(":/mylib/locale/german.qm")
    @

    ...both doesn't work!



  • @
    int main(int argc, char *argv[])
    {
    QApplication application(argc, argv);

    QTranslator libTranslator;
    ...
    MyLib::loadTranslation(libTranslator);
    QApplication::installTranslator(&libTranslator);
    
    ...
    return application.exec&#40;&#41;;
    

    }

    void loadTranslation(QTranslator& translator)
    {
    translator.load("/home/chris/myLib/locale/german.qm");
    }
    @

    LoadTranslator must be exported from the dll.

    The path to use for the load depends on your resource file. we can't tell you.



  • Ok, I made it so, Gerolf! Unfortunately, same behavior: MyApp german, but MyLib english strings/forms!

    libTranslator.load(...) returns true ... I despair soon!



  • With local file on hdd it works:

    @translator.load("/home/chris/mylib/locale/german.qm")@

    but if I use the resource, it doesn't work:

    @translator.load(":/locale/german.qm")@

    Both returns true! (?)



  • Your library needs to incorporate the resource file of the library. In order to not clash with names in your application, it's a good idea to put those resources into a virtual directory in the resources, e.g

    @
    :/mylibrary/locale/german.qm
    @

    Also, it may be necessary to explicitly initialize the library's ressources with "Q_INIT_RESOURCE":/doc/qt-4.8/qdir.html#Q_INIT_RESOURCE. The "Qt Resource System docs":/doc/qt-4.8/resources.html have some infos on that topic too (look at the end of the page).



  • It works now, thanks!

    @all:
    Big thanks for your help! You're great!

    Last thing: I load the Qt translations (qt_de.qm) in MyApp, must this be done also in MyLib for Qt strings (error messages etc.) in the library?



  • You're welcome - that's what this forums are made for :-)
    Please make sure to add [solved] to the title of the topic (the edit link is at the very first post).

    Regarding your last question:
    No, it's only needed in the application itself.



  • Ok, but Qt error strings are english only, allthough qt_de.qm is loaded! This returns an english message (it's in the library):

    @QIODevice::errorString()@

    ...or are these strings english only?



  • AFAIK, these translations are only for UI stuff like dialogs etc.
    Not for error strings, which you typically do not directly display to the end user.



  • Ok, but I found translations in qt_de.ts for error messages! I load qt_de.qm in MyApp, but my library doesn't use it! If I load qt_de.qm in MyLib, strings are still in english! Any special options to load it for libraries?


Log in to reply
 

Looks like your connection to Qt Forum was lost, please wait while we try to reconnect.