How to get a transfer to work outside the classroom?

I am writing an API that will be used when creating interfaces at work. The API allows the user to choose from a set of pre-built widgets and layouts so that within a short period of time it is possible to create several interfaces for different devices. There will be two translation files; one for the widget API (which comes with the library) and one more that the developer will create for user data in the interface. To simplify the work with the developer, I wanted the API to process the entire translation, passing the data name to the API, but I came to a stumbling block; I can't get the translator to recognize the translated text sent to him, but he recognizes local literals.

Here is a brief example of what I'm talking about.

class Object { public: Object(QString name) { m_Name = name; }; QString name() { return m_Name; }; private: QString m_Name; }; class MyWidget : public QPushButton, public Object { Q_OBJECT public: MyWidget(QString name); ~MyWidget(); void retranslate(); protected slots: void buttonPressed(); void changeEvent(QEvent* event); private: enum Language { ENGLISH, JAPANESE }; Language m_Language; QTranslator* m_pTranslator; }; MyWidget::MyWidget(QString name) :Object(name) // this does not work, but :Object(tr("TEST")) does { m_pTranslator = new QTranslator(); m_Language = ENGLISH; connect(this, SIGNAL(pressed()), this, SLOT(buttonPressed())); retranslate(); } MyWidget::~MyWidget() { delete m_pTranslator(); } void MyWidget::buttonPressed() { std::string qm; m_Language == ENGLISH ? m_Language = JAPANESE : m_Language = ENGLISH; m_Language == ENGLISH ? qm = "lang_en" : qm = "lang_jp"; qApp->removeTranslator(m_pTranslator); if(!m_pTranslator->load(qm.c_str())) std::cout << "Error loading translation file\n"; qApp->installTranslator(m_pTranslator); } void MyWidget::retranslate() { setText(tr(name().toStdString().c_str())); } void MyWidget::changeEvent(QEvent* event) { if(event->type() == QEvent::LanguageChange) retranslate(); else QWidget::changeEvent(event); } class MainWindow : public QMainWindow { Q_OBJECT public: MainWindow(); ~MainWindow(); private: MyWidget* m_pButton; }; MainWindow::MainWindow() { m_pButton = new MyWidget(tr("TEST")); // this is what I want to do, but this will not translate setCentralWidget(m_pButton); } MainWindow::~MainWindow() { delete m_pButton; } // main.cpp int main(int argc, char* argv[]) { QApplication app(argc, argv); MainWindow window; window.show(); return app.exec(); } 

I typed this manually, so there might be a few typos, but the concept still remains true - you have to call setText in the same class as your character. If you pass a literal to a class like I am here, it will be ignored. If I make a literal in the class, it works fine. This is a problem because I want the developer to pass the literal to the class and then give it a translation. The developer will still have to make their own translations, but I don’t want them to worry about working with translations.

Am I doing something wrong or is this a limitation of Qt?

+7
source share
1 answer

I suspect this is due to the fact that:

 m_pButton = new MyWidget(tr("TEST")); 

defines a string in the context of MainWindow , and you are trying to translate TEST in the context of MyWidget . You can get around this using the static tr() method on QObject . This will define TEST as a translation in the global QObject context. This can be done by adapting the button widget creation code as follows:

 m_pButton = new MyWidget(QObject::tr("TEST")); 

and MyWidget::retranslate() :

 setText(QObject::tr(name().toStdString().c_str())); 

Please note that for this you need to restore the translation files!

+4
source

All Articles