Creating a "self-translating" QWidget (with static text): is it possible?



  • Hello all,
    I want to create a QLabel (or QPushButton) with static text that does not depend on any variables or program status, for use in an application which offers language change at runtime.

    Common internet wisdom suggests to overwrite changeEvent for the base widget and call ```
    setText(tr("my very static text")) for every QLabel etc.

    I find this rather cumbersome, expecially when dealing with a larger number of labels. Therefore, I'd like to derive a QSelfTranslatingLabel which is initialized with a text once when it's created and calls something like setText(tr(that_text)) automatically in its own changeEvent handler.

    The problem with that approach is that that_text would be a variable, and you're supposed to use tr() with string literals, so that lupdate can create the language files correctly. Is there any clever way to do this? Any way that will work?

    Best regards, Michael


  • Qt Champions 2016

    @Heseltine
    Hi
    The system is based on the fact that you set the Text using the tr() macro and if you load another
    translation, you will set the text again so tr() can fetch the other/new translation.

    In theory you can make a label that points to the text and u can reload the text in this structure and on next
    repaint , the QLabel will use the new text.

    Another way is to use the meta system and get list of of QLabels and reset their text after the translator have been loaded. But im not sure if its a real benefit.

    Also note, if you build the UI using Creator, it already made alll these setText for you and it can be automatic.



  • @mrjj said in Creating a "self-translating" QWidget (with static text): is it possible?:

    The system is based on the fact that you set the Text using the tr() macro and if you load another
    translation, you will set the text again so tr() can fetch the other/new translation.

    Yes, I know. I'm already using that quite extensively.

    In theory you can make a label that points to the text and u can reload the text in this structure and on next
    repaint , the QLabel will use the new text.

    I'm not sure I understand this correctly - especially regarding the reload. I don't want to reload anything, at least not manually. I want to chage the translation, and use the changeEvent to redraw the label without explicitly telling the label which text to choose. The label should select the text itself, based on the text that was set initially and the translation that is now active. That means, I need a changeEvent() method for my QLabel that cannot contain a line like this

    setText(tr("STRING LITERAL"));
    

    because then I'd have to declare a new derived class for each label, which would be even more cumbersome than the standard way with tons of setText() in a central changeEvent() handler.

    The label should catch the language change, and then use the appropriate translation from the qm files (which will always exist, as the string should still be declared once - and translatable -
    when the label is created).

    Also note, if you build the UI using Creator, it already made alll these setText for you and it can be automatic.

    Unfortunately, the application already exists and doesn't use any UI from the creator.

    Cheers, michael.


  • Lifetime Qt Champion

    Hi,

    WARNING This is not tested, it's just to ensure the problem is understood correctly.

    Do you mean something like:

    class TranslatableLabel : public QLabel
    {
    public:
        TranslatableLabel(const QString& str, QWidget *parent=0):
            QLabel(parent),
            _str(str)
        {}
    
    private:
        void changeEvent(QEvent *event)
        {
            if (event->type() == QEvent::LanguageChange) {
               setText(tr(_str)));
            } else {
                QLabel::changeEvent(event);
            }
        }
    }
    
    MyWidgetConstructor(QWidget *parent) :
        QWidget(parent)
    {
        TranslatableLabel *label = new TranslatableLabel(QT_TR_NOOP("Hello"));
    }
    

    ?



  • @SGaist Thanks for the suggestion, I'll give it a try.


Log in to reply
 

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