关于qt:如何更改为在QML中的TabBar上动态添加的tabButtons

How to change to tabButtons added dynamically on a TabBar in QML

让我们假设我们使用qml javascript,在行tabBar.addItem和参数tabButton.createObject处添加一些TabButton

现在我想做的是,如果我更改语言,我也想更改TabButton的文本。

这怎么办?

我知道我可以在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()
}

您可以在此处找到完整的示例。