Как заставить перевод работать вне класса?

Я пишу API, который будет использоваться при создании интерфейсов на работе. API позволяет пользователю выбирать из набора готовых виджетов и макетов, чтобы можно было создать несколько интерфейсов для разных устройств за короткий период времени. Будет два файла перевода; один для виджетов API (которые поставляются с библиотекой), а другой, который разработчик создаст для пользовательских данных в интерфейсе. Чтобы упростить работу разработчика, я хотел, чтобы API обрабатывал весь перевод, передавая имя данных в API, но я наткнулся на камень преткновения; Я не могу заставить переводчика распознавать отправленный ему переведенный текст, но он распознает локальные буквальные строки.

Вот краткий пример того, о чем я говорю.

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();
 }

Я напечатал это вручную, поэтому может быть пара опечаток, но концепция все еще верна - вы должны вызвать setText в том же классе, в котором вы задали свою буквальную строку. Если вы передадите классу литерал, как я делаю здесь, он будет проигнорирован. Если я сделаю литерал в классе, он будет работать нормально. Это проблема, потому что я хочу, чтобы разработчик передавал классу литерал, а затем позволял ему выполнять перевод. Разработчику все равно придется делать свои собственные переводы, но я не хочу, чтобы они беспокоились об обработке переводов.

Я что-то делаю не так или это ограничение Qt?

8
задан Mat 6 October 2011 в 17:52
поделиться