Qt网站建议在代码中间存储可本地化的字符串,如下所示:
fileMenu = menuBar()->addMenu(tr("&File"));
但是,我应该如何多次存储项目中出现的字符串?将它们放在单例中有效但tr()
调用意味着我必须单独初始化它们:
struct MyLocalizableStrings
{
QString mErrorMessageFileNotFound;
QString mErrorMessageNoCanDoThis;
MyLocalizableStrings() :
mErrorMessageFileNotFound(QObject::tr("File not found.")),
mErrorMessageNoCanDoThis(QObject::tr("Operation is not possible at the moment."))
{}
};
笨拙而容易搞砸;我更喜欢将声明和初始化保持在一起。当然可以将一系列const char*
保留在专用命名空间中,但是在调用站点存在忘记tr()
的风险 - 整个方法严重不合标准。
有更好的想法吗?
答案 0 :(得分:1)
多次出现并且意图相同的字符串需要在一个或多个专用类中 - 所以你几乎把它弄好了。该类需要其翻译上下文,以便翻译人员更容易理解这些是常见消息。您还应该利用C ++ 11中的成员初始化来干燥:
首先,让我们建立一个基类和必要的帮助者:
#include <QCoreApplication>
template <typename Derived>
class LocalizableStringBase {
Q_DISABLE_COPY(LocalizableStringBase)
protected:
using S = QString;
static LocalizableStringBase * m_instance;
LocalizableStringBase() {
Q_ASSERT(!m_instance);
m_instance = this;
}
~LocalizableStringBase() {
m_instance = nullptr;
}
public:
static const Derived * instance() {
return static_cast<const Derived*>(m_instance);
}
void reset() {
auto self = static_cast<const Derived*>(this);
self->~Derived();
new (self) Derived();
}
};
#define DEFINE_LOCALIZABLE_STRINGS(Derived) \
template <> \
LocalizableStringBase<Derived> * LocalizableStringBase<Derived>::m_instance = {}; \
const Derived & Derived##$() { return *(Derived::instance()); }
然后,对于您需要的每组可本地化字符串:
// Interface
class MyLocalizableStrings : public LocalizableStringBase<MyLocalizableStrings> {
Q_DECLARE_TR_FUNCTIONS(MyLocalizableStrings)
public:
S errorMessageFileNotFound = tr("File not found.");
S errorMessageNoCanDoThis = tr("Operation is not possible at the moment.");
};
// Implementation
DEFINE_LOCALIZABLE_STRINGS(MyLocalizableStrings)
用法:
#include <QDebug>
void test() {
qDebug() << MyLocalizableStrings$().errorMessageFileNotFound;
}
int main(int argc, char ** argv)
{
QCoreApplication app{argc, argv};
MyLocalizableStrings str1;
test();
// Change language here
str1.reset();
test();
}
这是相当可读的,并且没有重复的标识符。它还避免了静态初始化命令惨败。