qt - 如何更改为 QML 中 TabBar 上动态添加的 tabButton

标签 qt qml

假设我们使用 qmljavascript 添加一些 TabButton,并使用 tabBar.addItem 行和 tabButton.createObject 作为参数.

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

如何做到这一点?

我知道我可以在组件上(并且我已经在真正的应用程序上使用它)从 C++ 类中获取一个连接(对信号使用react),我们在其中加载这样的翻译

Connections {
    target: qmlTranslator
    onLanguageChanged: {
      doSomething()
    }
}

我没有找到让它与此选项卡按钮一起使用的方法。我提供了一个简单的代码来说明我所拥有的:

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

编辑: 为什么这不起作用?

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

qml翻译器.cpp

#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

#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

在 main 上可以通过 qml 访问它

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

最佳答案

在这些情况下,您必须使用带有 QT_TR_NOOP 的模型(例如 ListModel),如 the docs 所示。 ,并使用 Repeater 将 TabButton 添加到 TabBar。

在此示例中,我使用了 3 种翻译:

translations
 ├── Lang-de.qm
 ├── Lang-en.qm
 └── Lang-es.qm

考虑到上述情况,解决方案如下:

翻译器.cpp

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

ma​​in.qml

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

您找到的完整示例here .

关于qt - 如何更改为 QML 中 TabBar 上动态添加的 tabButton,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/53724753/

相关文章:

c++ - 如何在 QPlainTextEdit 中只读一行?

qt - ListView 未按预期定位在布局中

c++ - 如何中止加载程序中的加载组件?

qt - QML:如何处理鼠标悬停?

qt - Qml:使用 Text 的 elide 属性和 textFormat:RichText

c++ - 字符串列表和字符串

ios - Qt和iOS之间如何通信?

qt - Qt中的OpengL glDrawBuffers()?

c++ - QShortcut 不工作

c++ - 无法在 QML ListView 中调用 Qt C++ 方法