How to change to tabButtons added dynamically on a TabBar in QML
让我们假设我们使用
现在我想做的是,如果我更改语言,我也想更改
这怎么办?
我知道我可以在c类的组件上(并且我已经在真正的app上运行过它)对来自信号的响应(对信号做出反应),我们可以像这样加载翻译
1 2 3 4 5 6 | Connections { target: qmlTranslator onLanguageChanged: { doSomething() } } |
我没有找到使它与该选项按钮一起使用的方法。我提供了一个简单的代码来说明我所拥有的:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 | import QtQuick 2.7 import QtQuick.Dialogs 1.2 import QtQuick.Layouts 1.3 import QtQuick.Controls 2.3 import QtQuick.Window 2.3 ApplicationWindow { visible: true width: 640 height: 480 title: qsTr("Tabbars") function assertCDataTabs () { var tabs = ["Config","Devices","IOs","Sounders","Zones"] for (var t in tabs) { tabBar.addItem(tabButton.createObject(tabBar, { text: QT_TRANSLATE_NOOP("main",t),"font.pixelSize": 14 })) } backgroundHome.visible=false; } header: TabBar { id: tabBar opacity:0.8 } Component { id: tabButton TabButton { font.pixelSize: 14 } } StackLayout { id: content currentIndex: tabBar.currentIndex anchors.fill: parent } Component.onCompleted: { assertCDataTabs() } } |
编辑:
为什么这不起作用?
1 2 3 4 5 6 7 8 9 10 11 12 | Connections { target: qmlTranslator onLanguageChanged: { var _contentData = tabBar.contentData if(_contentData.length > 0){ for(var i=0;i<_contentData.length;i++){ var textTrans = _contentData[i]['contentItem']['text'] tabBar.itemAt(i).text = qsTr(textTrans) } } } } |
qmltranslator.cpp
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 | #include"qmltranslator.h" #include <QApplication> #include <QDebug> #include <QDir> QmlTranslator::QmlTranslator(QQmlEngine *engine) { _translator = new QTranslator(this); _engine = engine; } void QmlTranslator::selectLanguage(QString language) { // working folder QDir dir = QDir(qApp->applicationDirPath()).absolutePath(); // #ifdef Q_OS_MACOS // crutch for Mac OS // dir.cdUp(); // dir.cdUp(); // dir.cdUp(); // #endif // qDebug() << dir.path(); QString languagesArray[] = {"en","pt","es","br","de","dk","fi","fr","it","lt","no","ro","tr","hu" }; for(int i=0;i<languagesArray->length();i++){ if(languagesArray[i] != language){ _translator->load(":/translations/" + QString("Lang-%1").arg(languagesArray[i])); qApp->removeTranslator(_translator); } } if (!_translator->load(":/translations/" + QString("Lang-%1").arg(language))) { qDebug() <<"Failed to load translation file, falling back to English"; } qApp->installTranslator(_translator); _engine->retranslate(); emit languageChanged(); } |
qmltranslator.h
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 | #ifndef QMLTRANSLATOR_H #define QMLTRANSLATOR_H #include <QObject> #include <QTranslator> #include <QQmlEngine> class QmlTranslator : public QObject { Q_OBJECT public: QmlTranslator(QQmlEngine *engine); Q_INVOKABLE void selectLanguage(QString language); signals: void languageChanged(); private: QTranslator *_translator; QQmlEngine *_engine; }; #endif // QMLTRANSLATOR_H |
主要通过qml
实现
1 2 3 4 5 | QQmlApplicationEngine engine; QmlTranslator qmlTranslator(&engine); // and register it as a context in Qml layer engine.rootContext()->setContextProperty("qmlTranslator", &qmlTranslator); engine.load(QUrl(QLatin1String("qrc:/main.qml"))); |
在这些情况下,您必须使用docs指示的带有QT_TR_NOOP的模型(例如ListModel),并将TabButton添加到TabBar上,并使用Repeater。
在此示例中,我使用3种翻译:
1 2 3 4 | translations a"?a"€a"€ Lang-de.qm a"?a"€a"€ Lang-en.qm a""a"€a"€ Lang-es.qm |
考虑到上述情况,解决方案如下:
translator.cpp
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 | #include"translator.h" #include <QGuiApplication> #include <QDirIterator> #include <QSettings> Translator::Translator(QQmlEngine *engine, QObject *parent) : QObject(parent), m_engine(engine) { m_translator = new QTranslator(this); m_dir = QDir(":translations"); m_languages.clear(); for(QString entry : m_dir.entryList()){ entry.remove(0, QString("Lang-").length()); entry.chop(extension.length()); m_languages.append(entry); } emit languagesChanged(); QSettings settings; QString lang =settings.value("Language/current", QLocale::system().bcp47Name()).toString(); selectLanguage(lang); } QStringList Translator::languages() const { return m_languages; } QString Translator::currentLanguage() const { return m_currentLanguage; } QString Translator::languageByCode(const QString &code) { QLocale lo(code); return QLocale::languageToString(lo.language()); } void Translator::selectLanguage(const QString &language) { qApp->removeTranslator(m_translator); if(m_languages.contains(language)){ QString file = QString("Lang-%1%2").arg(language).arg(extension); if(m_translator->load(m_dir.absoluteFilePath(file))){ m_currentLanguage = language; QSettings settings; settings.setValue("Language/current", language); emit currentLanguageChanged(); } } qApp->installTranslator(m_translator); m_engine->retranslate(); emit languageChanged(); } |
main.qml
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 | import QtQuick 2.7 import QtQuick.Layouts 1.3 import QtQuick.Controls 2.0 import QtQuick.Window 2.2 ApplicationWindow { visible: true width: 640 height: 480 title:"tabBars" ListModel{ id: tabmodel } function assertCDataTabs(){ var tabs = [QT_TR_NOOP("Configuration"), QT_TR_NOOP("Devices"), QT_TR_NOOP("Sounders"), QT_TR_NOOP("Zones")] for (var i in tabs) tabmodel.append({"text": tabs[i] }) } header: TabBar{ id: tabBar opacity:0.8 Repeater{ model: tabmodel TabButton{ text: qsTr(tabmodel.get(index).text) font.pixelSize: 14 } } } Column { width: parent.width * 0.95 spacing: 15 padding: 15 RowLayout { anchors.horizontalCenter: parent.horizontalCenter Repeater{ model: trans.languages Button{ id: btn property string code: modelData text: trans.languageByCode(code) onClicked: trans.selectLanguage(btn.code) Layout.preferredWidth: 100 Layout.preferredHeight: 50 highlighted: code == trans.currentLanguage } } } } Component.onCompleted: assertCDataTabs() } |
您可以在此处找到完整的示例。