2011-10-06 9 views
7

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?

Respuesta

4

Sospecho que esto se debe al hecho de que:

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

define una cadena en el contexto de MainWindow, y se intenta traducir TEST en el contexto de MyWidget. Puede eludir esto utilizando el método estático tr() en QObject. Esto definirá TEST como una traducción en el contexto global QObject. Esto se puede hacer mediante la adaptación del código de creación de control de botón de la siguiente manera:

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

y en MyWidget::retranslate():

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

en cuenta que necesita para regenerar sus archivos de traducción para que esto funcione!

+0

¡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

Cuestiones relacionadas