Estoy escribiendo una API para ser utilizada en la creación de interfaces en el trabajo. La API permite al usuario elegir entre un conjunto de widgets y diseños preconstruidos para que se puedan crear múltiples interfaces para diferentes unidades en un corto período de tiempo. Habrá dos archivos de traducción; uno para los widgets API (que vienen con la biblioteca) y otro que el desarrollador creará para datos personalizados en la interfaz. Para hacerlo más fácil para el desarrollador, quería que la API manejara todas las traducciones pasando el nombre de los datos a la API, pero he llegado a un obstáculo; No puedo hacer que el traductor reconozca el texto traducido que se le envió, pero reconocerá las cadenas literales locales.¿Cómo hacer que la traducción funcione fuera de la clase?
Aquí hay un breve ejemplo de lo que estoy hablando.
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();
}
he escrito esto con la mano por lo que podría ser un par de errores tipográficos, pero el concepto sigue siendo válida - usted tiene que llamar setText en la misma clase el conjunto de su cadena literal. Si pasa un literal a la clase, como hago aquí, será ignorado. Si hago el literal en la clase, funciona bien. Esto es un problema porque quiero que el desarrollador pase un literal a la clase y luego deje que haga la traducción. El desarrollador aún tendrá que hacer sus propias traducciones, pero no quiero que se preocupen por el manejo de las traducciones.
¿Estoy haciendo algo mal o es una limitación de Qt?
¡Sí, eso lo solucionó! Linguist pone todas las traducciones bajo QObject ahora, en lugar de dividirlas por clases como antes, pero eso no es realmente un tema importante y estoy más que contento con esta solución. – Richard