QTranslator doesn't load .qm file


  • Qt Champions 2016

    just testing translations of Qt 5.6 qt.labs.controls APP for Android and iOS
    trying to load the .qm files fails. Tried two ways to load - same result:

    #include <QGuiApplication>
    #include <QQmlApplicationEngine>
    #include <QDebug>
    #include <QTranslator>
    
    int main(int argc, char *argv[])
    {
        QGuiApplication::setAttribute(Qt::AA_EnableHighDpiScaling);
        qputenv("QT_LABS_CONTROLS_STYLE", "material");
        QGuiApplication app(argc, argv);
        QTranslator translator;
    //    if (translator.load("one_page_ui_" + QLocale::system().name(), ":/translations")) {
    //        app.installTranslator(&translator);
    //    } else {
    //        qDebug() << "cannot load translator " << QLocale::system().name();
    //    }
        if (translator.load(QLocale(), QLatin1String("one_page_ui"), QLatin1String("_"), QLatin1String(":/translations"))) {
            app.installTranslator(&translator);
        } else {
            qDebug() << "cannot load translator " << QLocale::system().name();
        }
    

    qm files are created by lrelease from my .pro:

    # Used to embed the qm files in resources
    TRANSLATIONS_FILES =
    
    # run LRELEASE to generate the qm files
    qtPrepareTool(LRELEASE, lrelease)
     for(tsfile, TRANSLATIONS) {
         qmfile = $$shadowed($$tsfile)
         qmfile ~= s,\\.ts$,.qm,
         qmdir = $$dirname(qmfile)
         !exists($$qmdir) {
             mkpath($$qmdir)|error("Aborting.")
         }
         command = $$LRELEASE -removeidentical $$tsfile -qm  $$qmfile
         system($$command)|error("Failed to run: $$command")
         TRANSLATIONS_FILES += $$qmfile
     }
    

    looking at the build-directories for Android or iOS the .qm files are deployed here:

    build-one_page_ui-Android_f_r_armeabi_v7a_GCC_4_9_Qt_5_6_0-Debug/

    • android-build
    • ....
    • Makefile
    • ...
    • translations/one_page_ui_de.qm
    • translations/one_page_ui.qm

    is there anything wrong ?


  • Lifetime Qt Champion

    Hi,

    Do you want to use these files from Qt's resource system or from a hard drive ? Because currently the path your are using in your translator.load call is within the resources but the build-directory note makes me think of a local deployment.


  • Qt Champions 2016

    @SGaist as I understood it right, using TRANSLATIONS_FILES in my .pro will make the .qm part of the resource system.
    inside my project dir there are the /translations/*.ts files
    build and run on Android or iOS then lrelease from my code above in .pro creates the .qm from .ts and if I take a look at the build dirs for android or ios I see the /translations/.qm files at the root of the build dir

    I didn't found any hint to do additional things to have the *.qm available from android or ios

    is there anything wrong ? this stuff is new to me - developing BlackBerry Cascades (Qt 4.8) apps all the translations stuff was handled by magic - I only had to define the languages.

    thx for any help

    BTW: this is the complete .pro:

    TEMPLATE = app
    
    QT += qml quick core
    CONFIG += c++11
    
    SOURCES += main.cpp
    lupdate_only {
        SOURCES +=  main.qml \
        common/*.qml \
        demo/*.qml
    }
    
    OTHER_FILES += main.qml \
        common/*.qml \
        demo/*.qml
    
    RESOURCES += qml.qrc
    
    # Additional import path used to resolve QML modules in Qt Creator's code model
    QML_IMPORT_PATH =
    
    # Default rules for deployment.
    include(deployment.pri)
    
    # var, prepend, append
     defineReplace(prependAll) {
         for(a,$$1):result += $$2$${a}$$3
         return($$result)
     }
    # Supported languages
    LANGUAGES = de en fr
    # Available translations
    TRANSLATIONS = $$PWD/translations/one_page_ui.ts
    TRANSLATIONS += $$prependAll(LANGUAGES, $$PWD/translations/one_page_ui_, .ts)
    
    # Used to embed the qm files in resources
    TRANSLATIONS_FILES =
    
    # run LRELEASE to generate the qm files
    qtPrepareTool(LRELEASE, lrelease)
     for(tsfile, TRANSLATIONS) {
         qmfile = $$shadowed($$tsfile)
         qmfile ~= s,\\.ts$,.qm,
         qmdir = $$dirname(qmfile)
         !exists($$qmdir) {
             mkpath($$qmdir)|error("Aborting.")
         }
         command = $$LRELEASE -removeidentical $$tsfile -qm  $$qmfile
         system($$command)|error("Failed to run: $$command")
         TRANSLATIONS_FILES += $$qmfile
     }
    
    

  • Lifetime Qt Champion

    OK, I think I'm following you now.

    If I understood correctly, that technique doesn't use Qt's resource system but create the files as a "resource to use by your application" i.e. it generates the files besides your application in a folder named "translations" that your should be able to access easily but not using :/ as protocol. If you want to embedded them within your executable you have to create a .qrc file for them.


  • Qt Champions 2016

    @SGaist thx for the hint. will try this
    but then I need the .qm files in my project dir
    this generates them into the build dir

    # run LRELEASE to generate the qm files
    qtPrepareTool(LRELEASE, lrelease)
     for(tsfile, TRANSLATIONS) {
         qmfile = $shadowed($tsfile)
         qmfile ~= s,\\.ts$,.qm,
         qmdir = $dirname(qmfile)
         !exists($qmdir) {
             mkpath($qmdir)|error("Aborting.")
         }
         command = $LRELEASE -removeidentical $tsfile -qm  $qmfile
         system($command)|error("Failed to run: $command")
         TRANSLATIONS_FILES += $qmfile
     }
    

    any idea how to change this to get the qm files from lrelease in my project dir /translations besides the .ts ?


  • Qt Champions 2016

    @SGaist found it. will post later the solution. it works now using .qrc. thx


  • Qt Champions 2016

    @SGaist this way it runs on Android and iOS as expected:

    TEMPLATE = app
    
    QT += qml quick core
    CONFIG += c++11
    
    SOURCES += main.cpp
    lupdate_only {
        SOURCES +=  main.qml \
        common/*.qml \
        demo/*.qml
    }
    
    OTHER_FILES += main.qml \
        common/*.qml \
        demo/*.qml
    
    RESOURCES += qml.qrc \
        translations.qrc
    
    # Additional import path used to resolve QML modules in Qt Creator's code model
    QML_IMPORT_PATH =
    
    # Default rules for deployment.
    include(deployment.pri)
    
    # T R A N S L A T I O N S
    
    # if languages are added:
    # 1. rebuild project to generate *.qm
    # 2. add existing .qm files to translations.qrc
    
    # if changes to translatable strings:
    # 1. Run Tools-External-Linguist-Update
    # 2. Run Linguist and do translations
    # 3. Build and run on iOS and Android to verify translations
    
    # Supported languages
    LANGUAGES = de en fr
    
    # used to create .ts files
     defineReplace(prependAll) {
         for(a,$$1):result += $$2$${a}$$3
         return($$result)
     }
    # Available translations
    TRANSLATIONS = $$PWD/translations/one_page_ui.ts
    TRANSLATIONS += $$prependAll(LANGUAGES, $$PWD/translations/one_page_ui_, .ts)
    # run LRELEASE to generate the qm files
    qtPrepareTool(LRELEASE, lrelease)
     for(tsfile, TRANSLATIONS) {
         qmfile = $$tsfile
         qmfile ~= s,\\.ts$,.qm,
         command = $$LRELEASE -removeidentical $$tsfile -qm  $$qmfile
         system($$command)|error("Failed to run: $$command")
     }
    

    thx for helping. now I understand it better how it works
    question: I'm using the app name (one_page_ui) sometimes inside .pro. Can I replace this using a variable ?

    BTW: is there a way to create a .qrc and add files dynamically from inside .pro ? would be great to eliminate this manual step.


  • Lifetime Qt Champion

    Usually you have the application name stored in the TARGET variable that you can then re-use.

    You can try to create your own custom target that you would run before the build starts.


  • Qt Champions 2016

    @SGaist now I added TARGET and changed creation of .ts files and reduced required code for lrelease
    here's my final way to deal with .ts / .qm:

    TEMPLATE = app
    TARGET = one_page_ui
    
    QT += qml quick core
    CONFIG += c++11
    
    SOURCES += main.cpp
    lupdate_only {
        SOURCES +=  main.qml \
        common/*.qml \
        demo/*.qml
    }
    
    OTHER_FILES += main.qml \
        common/*.qml \
        demo/*.qml
    
    RESOURCES += qml.qrc \
        translations.qrc
    
    # Additional import path used to resolve QML modules in Qt Creator's code model
    QML_IMPORT_PATH =
    
    # Default rules for deployment.
    include(deployment.pri)
    
    # T R A N S L A T I O N S
    
    # if languages are added:
    # 1. rebuild project to generate *.qm
    # 2. add existing .qm files to translations.qrc
    
    # if changes to translatable strings:
    # 1. Run Tools-External-Linguist-Update
    # 2. Run Linguist and do translations
    # 3. Build and run on iOS and Android to verify translations
    
    # Supported languages
    LANGUAGES = de en fr
    
    # used to create .ts files
     defineReplace(prependAll) {
         for(a,$$1):result += $$2$${a}$$3
         return($$result)
     }
    # Available translations
    tsroot = $$join(TARGET,,,.ts)
    tstarget = $$join(TARGET,,,_)
    TRANSLATIONS = $$PWD/translations/$$tsroot
    TRANSLATIONS += $$prependAll(LANGUAGES, $$PWD/translations/$$tstarget, .ts)
    # run LRELEASE to generate the qm files
    qtPrepareTool(LRELEASE, lrelease)
     for(tsfile, TRANSLATIONS) {
         command = $$LRELEASE $$tsfile
         system($$command)|error("Failed to run: $$command")
     }
    

    only manual step required is to run lupdate if translatable strings changed in src or qml


  • Qt Champions 2016

    FWIW: I have written a blog about this: http://j.mp/qt-i18n


  • Lifetime Qt Champion

    Thanks !


Log in to reply
 

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