如何使用Qt Linguist处理Qt UI文件?

3
我正在使用Qt Linguist翻译一个ui文件。我使用lupdate获取了它的ts文件,并翻译了其中的单词和短语。现在我想将其添加到我的代码中,但是从教程中发现似乎我必须在我的代码中每个单词和短语都加上tr()。我理解得对吗?我能否只加载一次已翻译的qm文件进行翻译?如果可以,那么我该如何在这个ui文件中实现呢?
提前致谢。
更新
根据Jens的建议更改属性后,在我的ui头文件中,我可以看到像这样的句子:
buttonSetupData->setText(QApplication::translate("MainWindow", "Set Data", 0, QApplication::UnicodeUTF8));

在Ajith的回答之后,我修改了我的代码,现在我的ui_main.h文件中的retranslateUi函数如下:

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

根据Ajith最新的回答,我更改了此表单中警告/消息框的每个字符串(例如):

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

通过lupdate工具,我可以读取所有这些字符串,进行翻译,并将其保存在一个 qm 文件中。但现在的问题是,它只能翻译 UI 中的字符串,而不能翻译执行后出现的警告/消息框中的字符串。

2个回答

1

我不太确定你想从这个问题中实现什么。我认为你正在寻找一种从C++代码中在运行时加载"qm"文件的方法。如果是这样,你需要做的就是使用QTranslator类。

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

更新

这对我来说是有效的...

mainwindow.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"));
}

mainwindow.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>

还有一个问题:似乎“lupdate”无法在警告窗口中找到文本字符串。你有什么想法吗? - E_learner
1
不应该是lupdate的问题。lupdate只是扫描文本文件并标记使用translate()函数的字符串,并填充.ts文件。请检查源文件,确保您想要的字符串已经使用tr()或translate()函数进行了标记。 - Ajith
1
不需要两个qm文件。lupdate的结果应该全部在一个ts文件中,处于不同的上下文中。作为测试,我认为你应该尝试从命令行运行lupdate。我现在无法测试它,但是尝试“lupdate *.{cpp,h} -ts test.ts”。QApplication :: translate()的第一个参数是上下文,请手动将其设置为不同的上下文。您可以指定不同的上下文,并且所有内容都应该放在同一个ts文件中。另外,请让我看一下您的.pro文件。 - Ajith
1
如果使用-extensions选项,则语法应为...'lupdate . -extensions cpp,h,ui -ts test.ts'。我曾尝试使用bash扩展,但由于当时我没有环境来检查我的命令,我忘记了第二个参数,这个参数应该是路径,在这种情况下是'.'或当前目录。无论如何,这些扩展名默认已包含在内,不需要指定它们。 - Ajith
1
我能够重现这个问题。我不确定为什么会发生这种情况。如果在retranslateUI()之前调用警告窗口,它会显示翻译后的文本。也许你可以开一个新的问题,其他人可能有更好的想法。另一种方法是使用以下代码创建自己的警告窗口: msgbox = new QMessageBox(QMessageBox::NoIcon, "", "", QMessageBox::NoButton, this); pbtn = msgbox->addButton("Ok", QMessageBox::AcceptRole);然后只为警告窗口中的文本创建自己的重新翻译函数。我成功地使用这种方法得到了一个翻译后的警告窗口。 - Ajith
显示剩余13条评论

1
基本上你所描述的是正确的。 QtDesigner/QtCreator 允许每个 UI 元素选择是否翻译其文本(请参见每个 UI 元素的属性)。如果选择翻译,则 tr() 将被放置到生成的 ui_xxx.h 文件中,然后像任何其他可翻译的单词一样呈现。

谢谢您的回答。请问我该如何在我的UI文件中使用它呢?如果我有一个cpp文件,我可以像教程中那样加载ts文件,但这里我的文件是.ui文件。我现在看到它在头文件中添加了"::translate..."。 - E_learner

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接