2017-02-19 96 views
0

我有這樣的事情:可選的Qt字符串翻譯

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

但它不工作。而且它看起來不太好。

+0

如何使用is_translatable參數並返回字符串的函數?這樣你就可以擺脫代碼重複,if條件(只在「翻譯功能」中使用它,而在其他情況下可以使用相同的功能) – Anon

+0

我認爲你濫用翻譯系統,在翻譯的應用程序中, UI字符串應該總是通過'tr()'選擇所需的語言以使它們顯示爲「未翻譯」。 –

回答

1

你可以使用預處理

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

,然後用它,所以你不需要外if了。

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

是的,這是最簡單的方法,但我想知道如果C++ 1x提供更好的方式lambda函數,只是不太喜歡使用預處理器。 – sikmir

+0

在這種情況下,使用宏比普通函數有什麼優勢? –

1

您可以使用拉姆達這樣:

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