[solved] Translation on the fly crashes



  • Hello everyone.

    I am developping an application in French and need to translate it into English aswell.
    It was working fine till yesterday when I had a new idea about the way to change the language. At first I was using a menu bar to translate the application, then I wanted to do it through a new widget.

    The former case worked perfectly but the latter one failed so I decided to remove it. The problem is... translation through the menu bar doesn't work anymore now.

    I have a MainWindow composed of a mainWidget and this mainwidget is used to display "other" widgets by using buttons.
    Anyway, here is how I implemented the translation :

    @MainWindow::MainWindow(QWidget *parent) :
    QMainWindow(parent),
    ui(new Ui::MainWindow)
    {
    translator = new QTranslator(0);
    QApplication::instance()->installTranslator(translator);

    connect(item1, SIGNAL(triggered()), this, (SLOT(changeToFrench())));
    connect(item2, SIGNAL(triggered()), this, (SLOT(changeToEnglish())));@
    

    @void MainWindow::changeToFrench()
    {
    if(!translator->isEmpty())
    QApplication::instance()->removeTranslator(translator);
    }

    void MainWindow::changeToEnglish()
    {
    translator->load("dcl_en",QApplication::applicationDirPath());
    }@

    @void MainWindow::changeEvent(QEvent *e)
    {
    if(e->type() == QEvent::LanguageChange)
    {
    ui->retranslateUi(this);
    retranslateUi();
    }
    QMainWindow::changeEvent(e);
    }

    void MainWindow::retranslateUi()
    {
    menu1->setTitle(tr("Langue"));
    menu2->setTitle(tr("A propos..."));
    item4->setText(tr("Paramètres système"));
    item1->setText("Français");
    item2->setText("English");
    item3->setText(tr("A propos..."));
    }@

    The translation works fine when I am in the main menu but if I wanna change the language when I am within an "other widget" (a widget called ui_identity for instance) it crashes with exit code -1073741819.

    Here is the code in "ui_identity" :

    @void ui_identity::changeEvent(QEvent *e)
    {
    if(e->type() == QEvent::LanguageChange)
    {
    ui->retranslateUi(this);
    }
    }@

    Any ideas ?


  • Lifetime Qt Champion

    Hi,

    What does a run trough the debugger tells you ?

    Are you sure all the pointers your are using are valid ?



  • Debugger tells me segmentation fault.
    The error is related to the translation



  • I can change the language through a setting window when I'm on the MainWindow but if I try while I'm on ui_identity wdget or some other widget it crashes...

    Really have no idea why.



  • @qApp->installTranslator(translator);@ this line causes the segmentation fault apparently..


  • Lifetime Qt Champion

    Are you sure translator is valid ?



  • @MainWindow::MainWindow(QWidget *parent) :
    QMainWindow(parent),
    ui(new Ui::MainWindow)
    {
    translator = new QTranslator(0);@

    I can translate the whole program while being on MainWindow. As soon as I go into a widget, I can no longer translate the program. It crashes :s


  • Lifetime Qt Champion

    That's in the MainWindow, how do you do it in your widget ?



  • I emit a signal from the widget which is then caught by the main window :
    WIDGET :
    @void ui_sys_settings::languageToEn()
    {
    emit toEnglish();
    }

    void ui_sys_settings::languageToFr()
    {
    emit toFrench();
    }@

    MAINWINDOW :
    @connect(sysSettings,SIGNAL(toEnglish()),this,SLOT(changeToEnglish()));
    connect(sysSettings,SIGNAL(toFrench()),this,SLOT(changeToFrench()));

    void MainWindow::changeToFrench()
    {
    if(!translator->isEmpty())
    qApp->removeTranslator(translator);
    }

    void MainWindow::changeToEnglish()
    {
    if(!translator->isEmpty())
    qApp->removeTranslator(translator);

    translator->load("dcl_en",QApplication::applicationDirPath());
    qApp->installTranslator(translator);
    

    }@


  • Lifetime Qt Champion

    Are you sure you need to re-install the translator ?



  • I only install it when I load the english language file. It is never installed otherwise


  • Lifetime Qt Champion

    Strange...
    Could you post/share a minimal compilable example that shows the problem ?



  • hmmm. post an example from my own program ?


  • Lifetime Qt Champion

    Rather the minimal code that reproduce the crash



  • Oh. The code that produce the crash is the code I have posted above.

    If I take the instruction " qApp->installTranslator(translator);" off, then it doesn't crash. But I have nothing translated lol


  • Lifetime Qt Champion

    Indeed, but with only pieces of code, I can't try to reproduce the crash.



  • oh. Do you want the full code of the class ?



  • Or I can send you the source files by email if you want. Maybe it could be easier for you to see what's wrong


  • Lifetime Qt Champion

    You can also use a service like "pastbin":http://pastebin.com/



  • Should I paste all my code with pastbin SGalst ?


  • Lifetime Qt Champion

    Only what is needed to build and trigger the crash



  • It is a graphic application. You would need the images files to be able to hit the button.

    Any way I can give it to you ?


  • Lifetime Qt Champion

    What do you mean by "images files to be able to hit the button" ?



  • In order to trigger the crash, you have to run the application then hit a button to load a widget. Then you have to hit another button to start the translation. (and then it crashes).

    If you want to trigger the crash yourself, you would need the whole program I think. (I have got too many classes ad I don't really know what is the minimal stuff you would need to be able to compile it)



  • It used to work fine before. Dunno what I changed, god damn it it's driving me crazy


  • Lifetime Qt Champion

    CVS to the rescue ! Or if it's not an option, the best technique is to strip your software down (or rebuild it from the ground) until you either have the bug again or it stop to happen (depends which direction you started with



  • Unfirtunately, I do not have any CVS system on my laptop (should have...)

    Have you ever used Qt debugger ? Look like it's really useless to me. It just show me the assembler code. What am I supposed to do with that ?


  • Lifetime Qt Champion

    All recent CVS system proposes to create local repositories that you can use.

    Generally this means that you are trying to debug a release version



  • I will think about it.

    I was debugging the debug version lol



  • god... I just fixed it !
    Thanks for your help and your time


  • Lifetime Qt Champion

    What was the problem ?

    You're welcome !

    Don't forget to update the thread's title prepending solved so other forum users may know a solution has been found :)



  • So let me explain the situation, it may helps people.

    I have a mainWindow which contains a mainWidget which in turns load several secondary widgets. (loaded one by one)

    When you add a translation in your application using qApp->installTranslator(& translator) then all the following calls to QObject::tr() will look up in the translator for a translated text. So you should call retranslateUi() after
    qApp->installTranslator() by reimplementing QWidget::changeEvent() and intercept any QEvent::LanguageChange event.

    In order to translate dynamically my secondary widgets I had to reimplement each widget's ChangeEvent(*event)
    function and call retranslateUi(), which is what I did.
    And this is what causes the problem.

    I was intercepting the event LanguageChange in the mainWidget and was calling retranslateUi() right after. LanguageChange was also intercepted by the secondary widget (which is a child of mainWidget) and retranslateUi() was called aswell.

    I had to remove the call of retranslateUi() in the mainWidget (There was nothing but tooltips to translate in this widget) then everything worked.
    Here is the code :

    MainWindow :
    @
    MainWindow::MainWindow(QWidget *parent) :
    QMainWindow(parent),
    ui(new Ui::MainWindow)
    {
    ...
    translator = new QTranslator();

    connect(sysSettings,SIGNAL(toEnglish()),this,SLOT(changeToEnglish()));
    connect(sysSettings,SIGNAL(toFrench()),this,SLOT(changeToFrench()));
    

    ...
    }

    void MainWindow::changeToFrench()
    {
    if ( translator )
    qApp->removeTranslator( translator );
    }

    void MainWindow::changeToEnglish()
    {
    if ( translator )
    qApp->removeTranslator( translator );

    translator->load( "dcl_en",QApplication::applicationDirPath());
    qApp->installTranslator( translator );
    

    }

    void MainWindow::changeEvent(QEvent *e)
    {
    if(e->type() == QEvent::LanguageChange)
    {
    ui->retranslateUi(this);
    retranslateUi();
    }
    QMainWindow::changeEvent(e);
    }

    void MainWindow::retranslateUi()
    {
    system_settings->setText(tr("Paramètres système"));
    about->setText(tr("A propos..."));
    }
    @

    MainWidget :
    @
    void mainWidget::changeEvent(QEvent *e)
    {
    if(e->type() == QEvent::LanguageChange)
    {
    retranslateUi();
    }
    }

    void mainWidget::retranslateUi()
    {
    ui->btn_addSpec->setToolTip(tr("xx"));
    ui->btn_delSpec->setToolTip(tr("xx"));
    ui->btn_corp->setToolTip(tr("xx"));
    ui->btn_curv->setToolTip(tr("xx"));
    ui->btn_identity->setToolTip(tr("xx"));
    ui->btn_eggs->setToolTip(tr("xx"));
    ui->btn_sante->setToolTip(tr("xx"));
    }
    @

    a secondary widget :
    @
    void ui_identity::changeEvent(QEvent *e)
    {
    if(e->type() == QEvent::LanguageChange)
    {
    ui->retranslateUi(this);
    this->translateUi();
    }
    }

    void ui_identity::translateUi()
    {
    QStringList list=(QStringList()<<tr("xxx")<<tr("yyy")<<tr("zzz"));
    ui->cbx_sex->addItems(list);

    ui->btn_modify->setToolTip(tr("ssssssss"));
    

    }
    @

    and the setting window called from a menubar :
    @
    ui_sys_settings::ui_sys_settings(QWidget *parent) :
    QWidget(parent),
    ui(new Ui::ui_sys_settings)
    {
    ui->setupUi(this);
    connect(ui->rdb_english, SIGNAL(clicked()),this,SIGNAL(toEnglish()));
    connect(ui->rdb_french, SIGNAL(clicked()),this,SIGNAL(toFrench()));

    if(parentWidget->getSettings()->getLanguage() == "French")
        this->ui->rdb_french->setChecked(true);
    else if(parentWidget->getSettings()->getLanguage() == "English")
        this->ui->rdb_english->setChecked(true);
    

    }

    void ui_sys_settings::changeEvent(QEvent *e)
    {
    if(e->type() == QEvent::LanguageChange)
    {
    ui->retranslateUi(this);
    }
    }
    @


Log in to reply
 

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