Another "change qt application language at runtime" thread.
-
Thanks a lot for your replies BilbonSacquet.
I'm afraid I'm rather thickheaded...
You make me very confused. In your previous post - the goal for me is to make it like shown in c), right? a) and b) are what? Just to show the difference?
So in c) you tell me that all my screen widgets, should inherit from this MyTranslation interface? And why inherit from Ui::MyWidget? I just don't get it.
And what about the EventFilter - what is that for?
My brain is soon gonna pop out of my skull.
Can you, or anyone else, explain it to me in other words? Or just spell it out more.
I'm sorry :(
But thank you so much for your time!
-
ok, I go perhaps too fast, I'm stressed right now with work and I will to help the directest way possible. But that's my bad.
That's true a) b) is just to explain the steps ... and c) the solution.
Yes, all widget which needs translation should inherits this class, that's necessary to take the message QEvent::LanguageChange and to make 'automatically' callback the translation functions. The event filter is necessary because the template MyTranslation doesn't inherit of the widget (it's just an QObject) function like event().
The message LanguageChange cycle is now:
app -> MyWidget::event() -> MyTranslator::eventFilter() -> MyWidget::Ui::MyWidget::retranslateUI() , MyWidget::translationChanged()
(if the function is redefined otherwise MyTranslator::translationChanged())Now why I inherits from Ui::MyClass, you will get the information from the Qt help. But mainly it makes all simplier in the handle of your widgets: same interface, you have all your children direct, you could use the on_mywidget_signal() slots without to connect/disconnct anything.
What I need is that all the widget has the function retranslateUi() accessible in the interface to be called by the template.I hope that I have helped you with the explanation and not make all darker like in the Morian mines :D
-
Okay I'm trying to work my way through it.
I'm writing the MyTranslation class now, but I get some errors:
@template <class T>
class MyTranslation : public QObject
{
T* m_t; //<------------- "Type 'T' could not be resolved"public:
MyTranslation() : m_t(0) {}
~MyTranslation() { if (m_t) m_t->QWidget::removeEventFilter(this); m_t = 0; }
...@Do I need to include something in order to do this?
-
Now I have verified/compiled the prototype given, I had done an error m_t->retranslateUi(-his- m_t);
Translation template - MyTranslator.h:
@
#include <QtCore/QObject>template <class T>
class MyTranslation : public QObject
{
T* m_t;public:
MyTranslation() : m_t(0) {}
~MyTranslation() { if (m_t) m_t->QWidget::removeEventFilter(this); m_t = 0; }void installTranslator(T* t) { m_t = t; m_t->QWidget::installEventFilter(this); }
protected:
virtual void translationChanged() {}bool eventFilter(QObject *obj, QEvent *event) { if (m_t && event->type() == QEvent::LanguageChange) { // retranslate designer form m_t->retranslateUi(m_t); // not automatally retranslation translationChanged(); } return false; }
};
@The widget - MyWidget.h:
@
#include <QtGui/QWidget>#include <ui_MyWidget.h>
#include <MyTranslator.h>class MyWidget: public QWidget, public Ui::MyWidget, public MyTranslation<MyWidget>
{
Q_OBJECTpublic: MyWidget(QWidget* parent = 0); virtual ~MyWidget(); protected: virtual void translationChanged();
};
@The MyWidget.cpp:
@
#include "MyWidget.h"MyWidget::MyWidget(QWidget* parent) : QWidget(parent)
{
setupUi(this);
installTranslator(this);
}MyWidget::~MyWidget() {}
void MyWidget::translationChanged()
{
qWarning() << "translator changed";
}
@And of course you need a MyWidget.ui with class MyWidget :) use the default widget. To make it faster I integrate on my current project, and redo a adapted copy/paste. It could have typos but should be ok now.
-
Thank you, but I still get the error in the start when writing:
@T* m_t;@
-
hmm .. which compiler are you using ?
-
mingw
-
you could try to replace 'template <class T>' by 'template <typename T>'
-
No change :(
-
and for no warnings compilation add: Q_UNUSED(obj); into the enventFilter()
-
But the error happens before this? I have only written:
@template <class T>
class MyTranslation : public QObject
{
T* m_t;public:
MyTranslation() : m_t(0) {}
~MyTranslation() { if (m_t) m_t->QWidget::removeEventFilter(this); m_t = 0; }
};@And it gives the error...
-
I have found some help in internet, seems that your interface (eclipse) not the compiler the problem.
"here some indication":stackoverflow.com/questions/6503551/opencv-type-iplimage-could-not-be-resolved
-
Thank you :)
I wrote the code in Qt Creator instead of Eclipse, and no errors appear in the MyTranslation.h file.
I am now trying to set up the "MyWidget.h" file.
First of all I can't inherit from Ui::MyWidget. Can this have something to do with MyWidget being a base class for all my ui's?
Secondly, if I leave out Ui::MyWidget, but inherit from MyTranslation<MyWidget>, my ui's seems to get errors, when it comes to the signal and slot connections made.
"reference to 'connect' is ambiguous"
-
If you couldn't inherits from the Ui::MyWidget you should adapt the code in the handler to find the restranslateUI(), or move the retranslateUI() call in the translationChanged() function.
yes, because you have 2x QObject inheritence. Use at the place the on_awidget_asignal() slots or in this case use QWidget::connect().
-
I'm sorry, I don't quite understand what you are saying? :(
-
Sorry, regarding the way I do multiple inheritence, you could find help in the Qt documentation: "Using a Design UI File in Your Application", pay a look to the last chapter:"Automatic Connections".
-
The link you gave me says
@QMetaObject::connectSlotsByName(this);@
Gives me this error: “'QObject' is an ambiguous base of 'MyWidget'”
- But you use QWidget:: Is there a reason for this?
-
You inherit twice from QObject:
@
class MyTranslation : public QObject
class MyWidget: public QWidget, public Ui::MyWidget, public MyTranslation<MyWidget>
@So you inherit from QObject via QWidget (which is a QObject subclass) and via MyTranslation. This is not supported!
-
BilbonSacquet you must have met this problem then?
-
It's supported, you should simply take care of the conflict. But we could do it through delegations (I take in consideration all what we say):
@
#include <QtCore/QObject>template <class T>
class MyTranslator : public QObject
{
T* m_t;public:
MyTranslator(T* widget)
: m_t(widget)
{
m_t->installEventFilter(this);
}~MyTranslator() { m_t->removeEventFilter(this); } bool eventFilter(QObject *obj, QEvent *event) { Q_UNUSED(obj); if (m_t && event->type() == QEvent::LanguageChange) { // not automatally retranslation m_t->T:translationChanged(); } return false; }
};
#include <QtGui/QWidget>
#include <ui_MyWidget.h>
#include <MyTranslator.h>class MyWidget: public QWidget
{
Q_OBJECTpublic: MyWidget(QWidget* parent = 0) : QWidget(parent), m_translator(this) { ui.setupUi(this); } virtual ~MyWidget() {} virtual void translationChanged() { ui.restranslateUi(); qWarning() << "translator changed"; } private: MyTranslator<MyWidget> m_translator; Ui::MyWidget ui;
};
@