可选的Qt字符串翻译

时间:2017-02-19 13:29:16

标签: c++ qt translation

我有这样的事情:

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

但它不起作用。此外,它看起来不太好。

4 个答案:

答案 0 :(得分:1)

你可以这样使用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();
}

答案 1 :(得分:1)

您可以使用预处理器

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

然后使用它,这样您就不再需要外部if

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

答案 2 :(得分:0)

您可以添加翻译方法:

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

答案 3 :(得分:0)

我找到了我要找的东西:

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