我有一个自定义类,我需要在其中保存新选择的语言并同时更改应用程序语言。基于QtCreator中的StackView示例项目的示例:
//main.cpp
int main(int argc, char *argv[])
{
QCoreApplication::setAttribute(Qt::AA_EnableHighDpiScaling);
QApplication app(argc, argv);
qmlRegisterType<CustomClass>("io.qt.CustomClass", 1, 0, "CustomClass");
QTranslator translator;
translator.load(":/EN.qm");
app.installTranslator(&translator);
QQmlApplicationEngine engine;
engine.load(QUrl(QStringLiteral("qrc:/main.qml")));
if (engine.rootObjects().isEmpty())
return -1;
return app.exec();
}
//customclass.h
class CustomClass : public QObject
{
Q_OBJECT
public:
explicit CustomClass(QObject *parent = nullptr) : QObject(parent) {}
Q_INVOKABLE void change(){
QTranslator translator;
QApplication::removeTranslator(&translator);
translator.load(":/CZ.qm");
QApplication::installTranslator(&translator);
//QQmlApplicationEngine * engine = qobject_cast<QQmlApplicationEngine *>(qmlEngine(this));
QQmlEngine *engine = QQmlEngine::contextForObject(this)->engine();
engine->retranslate();
}
};
//main.qml
...
CustomClass{id:test}
...
ItemDelegate {
text: qsTr("Page 1")
width: parent.width
onClicked: {
test.change()
drawer.close()
}
}...
//.pro file
QT += quick gui core
...
TRANSLATIONS = EN.ts CZ.ts
...
HEADERS += \
customclass.h在本例中,单击Page 1按钮应该会更改语言。
我的应用程序是基于StackView的,当我用这段代码调用函数时,一切似乎都正常。对字符串进行翻译。然而,当我在堆栈上推入一个新的项目时(比如从菜单中打开一个新的部分),那里的字符串又回到了更改前的原始语言。就像重新翻译只改变当前可见的字符串一样。
有人知道问题出在哪里吗?我怀疑这个引擎没有被正确获取。这是一个我需要注册(qmlRegisterType)才能在qml中使用的自定义类,我不确定如何正确地在那里获取引擎(因为引擎是在main函数中创建的)。
发布于 2020-01-28 00:41:31
我遇到了同样的问题。我找到的解决方案是在创建QTranslator对象时使用new操作符。这会导致在堆内存中而不是在堆栈中创建对象。如果它在堆栈内存中,QTranslator将在函数完成后删除(至少,我是这么理解的。我相信有更多C++经验的人可能会更好地解释它)。
因此,您的自定义类代码将如下所示:
//customclass.h
class CustomClass : public QObject
{
Q_OBJECT
public:
explicit CustomClass(QObject *parent = nullptr) : QObject(parent) {}
Q_INVOKABLE void change(){
QTranslator *translator = new QTranslator(qApp);
if (m_previousTranslator) {
QApplication::removeTranslator(m_previousTranslator);
m_previousTranslator->deleteLater();
m_previousTranslator = nullptr;
}
translator->load(":/CZ.qm");
m_previousTranslator = translator;
QApplication::installTranslator(translator);
QQmlEngine *engine = QQmlEngine::contextForObject(this)->engine();
engine->retranslate();
}
private:
QTranslator *m_previousTranslator = nullptr;
};注意,我添加了一个私有变量m_previousTranslator来执行一些内存管理。我还没有测试这个示例代码,但我在项目中使用了非常类似的代码,并且它工作正常
发布于 2019-07-04 04:02:32
我使用了一个肮脏的技巧来实现整个应用程序的重新翻译,而不需要在类中获取引擎。它不是完美的,但它是有效的。我在main中添加了一个循环,如下所示:
int returnValue = 0;
do
{
QApplication app(argc, argv);
QTranslator translator;
translator.load(":/translation/"+langString+".qm"); //langString might be the "CZ" as in the question example
app.installTranslator(&translator);
QQmlApplicationEngine engine;
engine.load(QUrl(QStringLiteral("qrc:/src/qml/main.qml")));
if (engine.rootObjects().isEmpty())
return -1;
returnValue = app.exec();
langString = settings.value("language").toString();
}
while(returnValue == TRANSLATION_RESTART);
return returnValue;因此在我的自定义类中,我只需使用以下命令退出应用程序:
qApp->exit(TRANSLATION_RESTART);我还保存了langString的值。这样,应用程序基本上就用新的语言重新启动了。
更新:虽然这是可行的,但最好将引擎和应用程序存储到使用问题中提到的方法处理翻译的单例类中。
https://stackoverflow.com/questions/56603484
复制相似问题