Как использовать Qt Linguist для файла пользовательского интерфейса Qt?

Я использую лингвист Qt для перевода файла ui. Я получил файл ts с помощью lupdate и перевел эти слова и фразы. Теперь я хочу добавить его в свой код, но из его руководства я обнаружил, что мне нужно добавить tr() к каждому слову и фразе в моем коде. Я правильно понял? Могу ли я просто загрузить переведенный файл qm один раз, чтобы сделать перевод? Если да, то как мне это сделать в этом ui файле?

Заранее спасибо.

Обновить

После изменения свойств, как упомянул Йенс, в моем заголовочном файле пользовательского интерфейса я вижу такие предложения, как:

buttonSetupData->setText(QApplication::translate("MainWindow", "Set Data", 0, QApplication::UnicodeUTF8));

После ответа Аджита я изменил свой код, и теперь моя функция retranslateUi в файле ui_main.h выглядит так:

void retranslateUi ( QMainWindow *MainWindow )
{
    QTranslator translator;
    translator.load ( " ...\Test.ts " );
    QApplication::installTranslator ( &translator );

    MainWindow->setWindowTitle ( QApplication::translate ("MainWindow",  "The Sentioscope - Beta v2.0 for Soccer", 0, QApplication::UnicodeUTF8));

    ...
}

Но это все равно не сработало.

последнее обновление

Моя текущая функция для чтения файла «.qm» выглядит так:

void MainWindow::translate()
{
     QTranslator translator;
     translator.load ( "Test.qm", "D:\\" );
     qApp->installTranslator ( &translator );
     retranslateUi ( this );
 }

Затем я вызываю эту функцию следующим образом:

MainWindow::MainWindow ( QWidget *parent ) : QMainWindow ( parent )
{
    setupUi(this);
    translate();
}

После последнего ответа Аджита я изменил каждую строку для окон предупреждений/сообщений в этой форме (например):

QMessageBox::warning( this, QMessageBox::tr("ERROR"), QMessageBox::tr("Invalid IP adress") );

К lupdate я могу прочитать все эти строки, перевести и сохранить их в файле qm. Теперь проблема в том, что он может переводить эти строки для пользовательского интерфейса, но не для окон предупреждений/сообщений после выполнения.


person E_learner    schedule 03.01.2013    source источник


Ответы (2)


Я не совсем уверен в том, чего вы хотите добиться от вопроса. Я думаю, вы ищете способ загрузить файлы «qm» во время выполнения из кода C++. Если это так, вам нужно будет использовать класс QTranslator. .

QTranslator translator;
translator.load("file.qm", "dir");
qApp->installTranslator(&translator);

Обновить

Это работало для меня.

главное окно.cpp

MainWindow::MainWindow(QWidget *parent) :
    QMainWindow(parent),
    ui(new Ui::MainWindow),
    isChinese(false)
{
    ui->setupUi(this);
    msgbox = new QMessageBox(QMessageBox::NoIcon, "", "", QMessageBox::NoButton, this);
    pbtn = msgbox->addButton("Ok", QMessageBox::AcceptRole);

    doRetranslate();

    QObject::connect(ui->pushButton, SIGNAL(clicked()), this, SLOT(doTranslate()));
    QObject::connect(ui->pushButton, SIGNAL(clicked()), msgbox, SLOT(show()));
}

MainWindow::~MainWindow()
{
    delete ui;
}

void MainWindow::doTranslate()
{
    QTranslator translator;
    if (!isChinese) {
        translator.load("test_zh_TW.qm", "../TestTranslator");
        qApp->installTranslator(&translator);
        isChinese = true;
    } else {
        translator.load("", ""); // Default is english
        qApp->installTranslator(&translator);
        isChinese = false;
    }
    ui->retranslateUi(this);
    doRetranslate();
}

void MainWindow::doRetranslate()
{
    msgbox->setWindowTitle(QObject::tr("ERROR"));
    msgbox->setText(QObject::tr("Invalid IP adress"));
    pbtn->setText(QObject::tr("Ok"));
}

главное окно.h

#ifndef MAINWINDOW_H
#define MAINWINDOW_H

#include <QMainWindow>
#include <QMessageBox>
#include <QPushButton>

namespace Ui {
class MainWindow;
}

class MainWindow : public QMainWindow
{
    Q_OBJECT

public:
    explicit MainWindow(QWidget *parent = 0);
    ~MainWindow();

    void doRetranslate();
public slots:
    void doTranslate();

private:
    Ui::MainWindow *ui;
    bool isChinese;
    QMessageBox *msgbox;
    QPushButton *pbtn;
};

#endif // MAINWINDOW_H

mainwindow.ui

<?xml version="1.0" encoding="UTF-8"?>
<ui version="4.0">
 <class>MainWindow</class>
 <widget class="QMainWindow" name="MainWindow">
  <property name="geometry">
   <rect>
    <x>0</x>
    <y>0</y>
    <width>400</width>
    <height>300</height>
   </rect>
  </property>
  <property name="windowTitle">
   <string>MainWindow</string>
  </property>
  <widget class="QWidget" name="centralWidget">
   <widget class="QLabel" name="label">
    <property name="geometry">
     <rect>
      <x>100</x>
      <y>70</y>
      <width>181</width>
      <height>17</height>
     </rect>
    </property>
    <property name="text">
     <string>Hello World!</string>
    </property>
    <property name="alignment">
     <set>Qt::AlignCenter</set>
    </property>
   </widget>
   <widget class="QPushButton" name="pushButton">
    <property name="geometry">
     <rect>
      <x>140</x>
      <y>120</y>
      <width>93</width>
      <height>27</height>
     </rect>
    </property>
    <property name="text">
     <string>translate</string>
    </property>
   </widget>
  </widget>
  <widget class="QMenuBar" name="menuBar">
   <property name="geometry">
    <rect>
     <x>0</x>
     <y>0</y>
     <width>400</width>
     <height>23</height>
    </rect>
   </property>
  </widget>
  <widget class="QToolBar" name="mainToolBar">
   <attribute name="toolBarArea">
    <enum>TopToolBarArea</enum>
   </attribute>
   <attribute name="toolBarBreak">
    <bool>false</bool>
   </attribute>
  </widget>
  <widget class="QStatusBar" name="statusBar"/>
 </widget>
 <layoutdefault spacing="6" margin="11"/>
 <resources/>
 <connections>
  <connection>
   <sender>pushButton</sender>
   <signal>clicked()</signal>
   <receiver>label</receiver>
   <slot>update()</slot>
   <hints>
    <hint type="sourcelabel">
     <x>199</x>
     <y>165</y>
    </hint>
    <hint type="destinationlabel">
     <x>206</x>
     <y>114</y>
    </hint>
   </hints>
  </connection>
 </connections>
</ui>
person Ajith    schedule 03.01.2013
comment
Я хочу загрузить его в пользовательский интерфейс или его заголовочный файл, а не в cpp, потому что я пробовал именно так, как вы упомянули, но это не удалось. - person E_learner; 03.01.2013
comment
Я не знаю, можно ли это сделать из файла .ui во время выполнения. Но для предложенного мной метода вам нужно будет сделать перезагрузку уже отображаемых виджетов. Что-то вроде QMetaObject::invokeMethod(this, "doReload", Qt::QueuedConnection); - person Ajith; 03.01.2013
comment
Эта ссылка может быть полезна [qtcenter.org/wiki/ .. В нем упоминается, что все формы, разработанные в Qt Designer, имеют метод retranslateUi(). Это должно быть вызвано для повторного перевода спроектированных строк. - person Ajith; 03.01.2013
comment
Спасибо за ваш ответ. Я обновил вопрос в соответствии с ним. - person E_learner; 03.01.2013
comment
переводчик.загрузить ( ...\Test.ts ); ‹--- Вам необходимо предоставить файл .qm. - person Ajith; 04.01.2013
comment
Еще один вопрос: похоже, что «lupdate» не может найти текстовые строки в окнах предупреждений. У вас есть какие-нибудь идеи по этому поводу? - person E_learner; 04.01.2013
comment
Не должно быть проблемы с обновлением. lupdate просто сканирует текстовые файлы и записывает строки, помеченные функцией translate(), и заполняет файл .ts. Проверьте исходные файлы, чтобы убедиться, что нужные строки помечены функциями tr() или translate(). - person Ajith; 06.01.2013
comment
В исходном файле все эти строки для предупреждений связаны с функциями tr или translate(), но lupdate по-прежнему не может их найти. Вот что меня смущает. - person E_learner; 06.01.2013
comment
Я никогда не сталкивался с такой проблемой с lupdate. Так что я не мог сказать. - person Ajith; 07.01.2013
comment
Хорошо, я решил это. Теперь он может читать все эти строки в предупреждениях. Но при этом у меня есть еще один файл qm, то есть вместе с qm для пользовательского интерфейса у меня есть целых два файла qm. И в моем коде, когда я читаю их обоих двумя строками и делаю retranslateUi, он переводит только пользовательский интерфейс, но не предупреждения. Как я могу это решить? Спасибо. - person E_learner; 07.01.2013
comment
Нет необходимости в двух файлах qm. Все результаты lupdate должны быть в одном ts-файле в разных контекстах. В качестве теста, думаю, стоит попробовать запустить lupdate из командной строки. Я не могу проверить это прямо сейчас, но попробуйте 'lupdate *.{cpp,h} -ts test.ts'. Первый параметр QApplication::translate() — это контекст, вручную задайте для него другой контекст. Вы можете указать разные контексты, и все они должны идти в один и тот же файл ts. Кроме того, позвольте мне взглянуть на ваш файл .pro. - person Ajith; 07.01.2013
comment
Спасибо за ваш ответ. Я всегда использую командную строку для lupdate, и после вашего предложения я попытался использовать ее как lupdate *.{cpp,h,ui} -ts Test.ts, но это не удалось. Затем, прочитав его файл справки, я использовал его как lupdate -extensions *.{cpp,h,ui} -ts Test.ts, но файл ts пуст. Не могли бы вы помочь мне? - person E_learner; 08.01.2013
comment
При использовании -extensions синтаксис должен быть...'lupdate . -расширения cpp,h,ui -ts test.ts'. Я пытался использовать расширение bash, но, поскольку в то время у меня не было среды для проверки моей команды, я забыл второй аргумент, который в данном случае должен быть путем '.' или текущий реж. В любом случае эти расширения включены по умолчанию, указывать их не нужно. - person Ajith; 08.01.2013
comment
пожалуйста, позвольте мне задать еще один вопрос: я вручную добавил tr для каждой строки предупреждения, которая может быть обнаружена lupdate. Затем, после вызова всех этих строк в одном файле ts и их перевода, он по-прежнему показывал мне переведенные слова только для пользовательского интерфейса, но не для предупреждений. Как я могу это решить? Спасибо. - person E_learner; 08.01.2013
comment
На данный момент я действительно не знаю, что происходит с вашей стороны.. Можете ли вы опубликовать что-нибудь, что я могу попробовать в своей среде.. - person Ajith; 08.01.2013
comment
Пожалуйста, взгляните на эту строку в моем коде: QMessageBox::warning(это, QMessageBox::tr(ОШИБКА), QMessageBox::tr(Недопустимый IP-адрес));. Затем после lupdate в файле ts он показал строку Invalid IP address в части QMessageBox, и я перевел ее. Но после вызова файла qm он все равно не перевел его на самом деле. Я думаю, что команда retranslateUi(this) как-то связана с этим, но я не могу сказать, как именно. Есть ли у вас какие-либо идеи? - person E_learner; 08.01.2013
comment
Я смог воспроизвести проблему. Я не уверен, почему это происходит. Если я вызову окно предупреждения перед retranslateUI(), оно отобразится с переведенным текстом. Может быть, вы можете открыть другой вопрос, у кого-то может быть лучшая идея. Альтернативный способ — создать собственное окно предупреждения с помощью... msgbox = new QMessageBox(QMessageBox::NoIcon, , , QMessageBox::NoButton, this); pbtn = msgbox-›addButton(Ok, QMessageBox::AcceptRole); И тогда у вас есть собственная функция повторного перевода только для текста в окне предупреждения. Я смог использовать это, чтобы получить переведенное окно предупреждения. - person Ajith; 09.01.2013
comment
Еще раз спасибо. На данный момент я должен позволить ему работать только неэффективным способом. - person E_learner; 09.01.2013

Почти правильно то, что вы описываете. QtDesigner/QtCreator позволяет каждому элементу пользовательского интерфейса выбирать, следует ли переводить его тексты или нет (см. свойства каждого элемента пользовательского интерфейса). Если выбран перевод, то tr() помещается в сгенерированный файл ui_xxx.h и оттуда представляется как любое другое переводимое слово.

person Jens    schedule 03.01.2013
comment
Спасибо за ваш ответ. Не могли бы вы сказать мне, как я могу использовать его в своем файле пользовательского интерфейса? Если у меня есть файл cpp, я могу загрузить файл ts, как в учебнике, но здесь мой файл имеет расширение .ui. Я видел, что он добавил ::tranlate... в свой заголовочный файл. - person E_learner; 03.01.2013