2011-10-06 10 views
7

Tôi đang viết một API để sử dụng trong việc tạo Giao diện tại nơi làm việc. API cho phép người dùng chọn từ một tập hợp các tiện ích và bố cục dựng sẵn để có thể tạo nhiều giao diện cho các đơn vị khác nhau trong một khoảng thời gian ngắn. Sẽ có hai tệp dịch; một cho các tiện ích API (đi kèm với thư viện) và một tiện ích khác mà nhà phát triển sẽ tạo cho dữ liệu tùy chỉnh trong giao diện. Để làm cho nó dễ dàng hơn trên các nhà phát triển tôi muốn API để xử lý tất cả các bản dịch bằng cách chuyển tên của dữ liệu vào API, nhưng tôi đã đi đến một trở ngại; Tôi không thể yêu cầu người phiên dịch nhận ra văn bản đã dịch được gửi tới nó, nhưng nó sẽ nhận ra các chuỗi chữ của địa phương.Làm thế nào để có được bản dịch để làm việc bên ngoài lớp học?

Đây là một ví dụ ngắn về những gì tôi đang nói đến.

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

Tôi đã nhập bằng tay để có thể có một vài lỗi chính tả, nhưng khái niệm vẫn đúng - bạn phải gọi setText trong cùng một lớp bạn đặt chuỗi chữ của bạn. Nếu bạn chuyển một chữ vào lớp, như tôi đang làm ở đây, nó sẽ bị bỏ qua. Nếu tôi làm cho chữ trong lớp nó hoạt động tốt. Đây là một vấn đề bởi vì tôi muốn các nhà phát triển để vượt qua một chữ cho lớp và sau đó để cho nó làm bản dịch. Các nhà phát triển vẫn sẽ cần phải thực hiện bản dịch của riêng mình, nhưng tôi không muốn họ lo lắng về việc xử lý các bản dịch.

Tôi có làm gì sai hoặc đây có phải là giới hạn Qt không?

Trả lời

4

Tôi nghi ngờ điều này là do thực tế rằng:

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

định nghĩa một chuỗi trong bối cảnh MainWindow, và bạn cố gắng để dịch TEST trong bối cảnh MyWidget. Bạn có thể phá vỡ điều này bằng cách sử dụng phương thức tĩnh tr() trên QObject. Điều này sẽ xác định TEST làm bản dịch trong ngữ cảnh toàn cầu QObject. Điều này có thể được thực hiện bằng cách áp dụng các nút mã tạo phụ tùng như sau:

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

và trong MyWidget::retranslate():

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

Lưu ý rằng bạn cần phải tạo file bản dịch của mình để làm việc này!

+0

Đúng, đã sửa nó! Linguist đặt tất cả các bản dịch theo QObject ngay bây giờ, thay vì chia nhỏ chúng thành các lớp như trước đây, nhưng đó không thực sự là một vấn đề quan trọng và tôi rất hài lòng với giải pháp này. – Richard