【问题标题】:Optional Qt string translation可选的 Qt 字符串翻译
【发布时间】:2017-02-19 13:29:16
【问题描述】:

我有这样的事情:

void FooWidget:showSomeDialog(bool is_translatable)
{
  QMessageBox mbox(this);
  if (is_translatable)
  {
    mbox.setWindowsTitle(tr("Title"));
    mbox.setText(tr("Text"));
    mbox.setInformativeText(tr("InformativeText"));
    mbox.addButton(tr("Button1"), QMessageBox::YesRole);
    mbox.addButton(tr("Button2"), QMessageBox::NoRole);
    ...
  } else {
    mbox.setWindowsTitle(QLatin1String("Title"));
    mbox.setText(QLatin1String("Text"));
    mbox.setInformativeText(QLatin1String("InformativeText"));
    mbox.addButton(QLatin1String("Button1"), QMessageBox::YesRole);
    mbox.addButton(QLatin1String("Button2"), QMessageBox::NoRole);
    ...
  }
  mbox.exec();
}

避免重复的更好方法是什么?

我尝试过像这样使用 lambda 函数:

  auto func = is_translatable
              ? [](const char *str) -> QString { return tr(str); }
              : [](const char *str) -> QString { return QLatin1String(str); };

但它不起作用。而且它看起来不太好。

【问题讨论】:

  • 接受 is_translatable 参数并返回字符串的函数怎么样?这样你就摆脱了代码重复,if 条件(你只在“翻译函数”中使用它,并且相同的函数可以用于其他情况。
  • 我认为您误用了翻译系统。在已翻译的应用程序中,UI 字符串应始终通过 tr()。选择所需的语言使其显示为“未翻译”。

标签: c++ qt translation


【解决方案1】:

你可以使用预处理器

#define TRANSLATE(cond, str) (cond) ? tr(str) : QLatin1String(str)

然后使用它,这样你就不再需要外部的if了。

mbox.setWindowsTitle(TRANSLATE(is_translatable, "Title"))

【讨论】:

  • 是的,这是我想到的最简单的方法,但我想知道 C++1x 是否提供了使用 lambda 函数的更好方法。只是不太喜欢使用预处理器。
  • 在这种情况下使用宏比普通函数有什么优势?
【解决方案2】:

你可以这样使用 lambda:

void FooWidget:showSomeDialog(bool is_translatable)
{
    auto makeLatin = [](auto const& str) {return QLatin1String(str);};
    auto lambda = [this](auto& fun) {
        this->mbox.setWindowsTitle(fun("Title"));
        this->mbox.setText(fun("Text"));
        this->mbox.setInformativeText(fun("InformativeText"));
        this->mbox.addButton(fun("Button1"), QMessageBox::YesRole);
        this->mbox.addButton(fun("Button2"), QMessageBox::NoRole);
        ...
    };
    if (is_translatable)
    {
        lambda(tr);
    } else {
        lambda(makeLatin);
    }
    mbox.exec();
}

【讨论】:

    【解决方案3】:

    你可以添加一个翻译方法:

    void FooWidget::translate(bool is_translatable, QString value)
    {
       if(is_translatable) return tr(value)
       return QLatin1String(value);
    }
    
    void FooWidget:showSomeDialog(bool is_translatable)
    {
      QMessageBox mbox(this);
      mbox.setWindowsTitle(translate(is_translatable, "Title");
      mbox.setText(translate(is_translatable, "Text"));
      mbox.setInformativeText(translate(is_translatable, "InformativeText"));
      mbox.addButton(translate(is_translatable, "Button1"), QMessageBox::YesRole);
      mbox.addButton(translate(is_translatable, "Button2"), QMessageBox::NoRole);
      mbox.exec();
    }
    

    如果 is_translatable 可以是 FooWidget 的成员,那么阅读起来也会更整洁:

    void FooWidget::translate(QString value)
    {
       if(this->is_translatable) return tr(value)
       return QLatin1String(value);
    }
    
    void FooWidget:showSomeDialog()
    {
      QMessageBox mbox(this);
      mbox.setWindowsTitle(translate("Title");
      mbox.setText(translate("Text"));
      mbox.setInformativeText(translate("InformativeText"));
      mbox.addButton(translate("Button1"), QMessageBox::YesRole);
      mbox.addButton(translate("Button2"), QMessageBox::NoRole);
      mbox.exec();
    }
    

    【讨论】:

      【解决方案4】:

      我找到了我要找的东西:

      void FooWidget:showSomeDialog(std::function<QString(const char*)> tr)
      {
        QMessageBox mbox(this);
        mbox.setWindowsTitle(tr("Title"));
        mbox.setText(tr("Text"));
        mbox.setInformativeText(tr("InformativeText"));
        mbox.addButton(tr("Button1"), QMessageBox::YesRole);
        mbox.addButton(tr("Button2"), QMessageBox::NoRole);
        ...
        mbox.exec();
      }
      

      用法:

      showSomeDialog([](const char* s){ return QString::fromLatin1(s); });
      showSomeDialog([](const char* s){ return FooWidget::tr(s); });
      

      【讨论】:

        猜你喜欢
        • 2011-08-02
        • 1970-01-01
        • 1970-01-01
        • 2014-05-21
        • 2010-10-23
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多