首页 > 解决方案 > 动态重新翻译 UI。按钮排列不正确

问题描述

所以我有这个应用程序,我可以在设置窗口中动态更改语言。一切都很好,除了一个问题:

如果我从西班牙语更改:

f156daef-acf1-406c-8daf-99d2767f0a5f-image.png

对德语:

f5194bf3-33de-4bf1-bafc-6c7d0c500b54-image.png

你可以看到右下角的按钮(说SCHLIEßEN)没有安排好。

如果我重新打开弹出窗口。不再有问题,它可以正确重新排列:

efd6392e-ae1a-4044-a001-91cae55fe513-image.png

这是我们必须忍受的某种错误还是有解决方案?

这是此弹出窗口的代码:

import QtQuick 2.15
import QtQuick.Layouts 1.15
import QtQuick.Controls 2.15

import LanguageSelectors 1.0

Dialog {
    id: root
    x: 100
    y: 100
    width: 400
    height: 600
    modal: true
    focus: true
    closePolicy: Popup.CloseOnEscape | Popup.CloseOnPressOutsideParent

    title: qsTr("Settings")

    property alias countOfQuestions: countOfQuestionsSpinBox.value

    property bool darkModeOn

    ColumnLayout {
        id: columnLayout
        RowLayout {
            Label {
                text: qsTr("Light")
                font.pointSize: 13.5
            }
            Switch {
                id: colorModeSwitch
                position: darkModeOn ? 1.0 : 0.0

                onPositionChanged: {
                    if (position === 0.0) {
                        root.darkModeOn = false
                    } else {
                        root.darkModeOn = true
                    }
                }
            }
            Label {
                text: qsTr("Dark")
                font.pointSize: 13.5
            }
        }
        RowLayout {
            Label {
                text: qsTr("Count of Questions:")
                font.pointSize: 13.5
            }
            SpinBox {
                Layout.fillWidth: true
                id: countOfQuestionsSpinBox
                from: 0
                to: 999
                editable: true
            }
        }
        RadioButton {
            checked: LanguageSelector.language === LanguageSelector.German
            text: qsTr("German")
            onPressed: {
                LanguageSelector.language = LanguageSelector.German
            }
        }
        RadioButton {
            checked: LanguageSelector.language === LanguageSelector.English
            text: qsTr("English")
            onPressed: {
                LanguageSelector.language = LanguageSelector.English
            }
        }
        RadioButton {
            checked: LanguageSelector.language === LanguageSelector.Spanish
            text: qsTr("Spanish")
            onPressed: {
                LanguageSelector.language = LanguageSelector.Spanish
            }
        }
    }

    standardButtons: Dialog.Close
}

我通过分配给语言选择器来更改语言:

class LanguageSelector : public QObject {
    Q_OBJECT
    Q_PROPERTY(Language language READ language WRITE setLanguage NOTIFY
                   languageChanged)
public:
    enum Language { German, English, Spanish };
    Q_ENUM(Language)

    explicit LanguageSelector(QObject *parent = nullptr);

    Language language() const;
    void setLanguage(Language newLanguage);

    QTranslator *getTranslator() const;

private:
    QTranslator *mAppTranslator;
    QTranslator *mQtBaseTranslator;
    QTranslator *mQtQuickControlsTranslator;
    Language mLanguage;

    void loadGerman();
    void loadEnglish();
    void loadSpanish();

    void loadLanguage(const QLocale::Language &newLanguage);

signals:
    void languageChanged();
};
#include <QDebug>
#include <QGuiApplication>
#include <QLocale>
#include <QMetaEnum>
#include <QTranslator>

LanguageSelector::LanguageSelector(QObject *parent)
    : QObject{parent}, mAppTranslator{new QTranslator{this}},
      mQtBaseTranslator{new QTranslator{this}}, mQtQuickControlsTranslator{
                                                    new QTranslator{this}}
{
}

LanguageSelector::Language LanguageSelector::language() const
{
    return mLanguage;
}

void LanguageSelector::setLanguage(Language newLanguage)
{
    switch (newLanguage) {
    case Language::German:
        loadLanguage(QLocale::German);
        break;
    case Language::English:
        qApp->removeTranslator(mAppTranslator);
        qApp->removeTranslator(mQtBaseTranslator);
        qApp->removeTranslator(mQtQuickControlsTranslator);
        break;
    case Language::Spanish:
        loadLanguage(QLocale::Spanish);
        break;
    }
    mLanguage = newLanguage;
    emit languageChanged();
}

QTranslator *LanguageSelector::getTranslator() const
{
    return mAppTranslator;
}

void LanguageSelector::loadLanguage(const QLocale::Language &newLanguage)
{
    qApp->removeTranslator(mAppTranslator);
    if (!mAppTranslator->load(QLocale(newLanguage), QStringLiteral("quiz"),
                              QStringLiteral("."),
                              QStringLiteral(":/translations"))) {
        auto metaEnum = QMetaEnum::fromType<QLocale::Language>();
        qDebug() << tr("load app translator language %1 failed")
                        .arg(metaEnum.valueToKey(newLanguage));
    }
    qApp->installTranslator(mAppTranslator);

    qApp->removeTranslator(mQtBaseTranslator);
    if (!mQtBaseTranslator->load(QLocale(newLanguage), QStringLiteral("qtbase"),
                                 QStringLiteral("."),
                                 QStringLiteral(":/translations"))) {
        auto metaEnum = QMetaEnum::fromType<QLocale::Language>();
        qDebug() << tr("load qt base translator language %1 failed")
                        .arg(metaEnum.valueToKey(newLanguage));
    }
    qApp->installTranslator(mQtBaseTranslator);

    qApp->removeTranslator(mQtQuickControlsTranslator);
    if (!mQtQuickControlsTranslator->load(
            QLocale(newLanguage), QStringLiteral("qtquickcontrols"),
            QStringLiteral("."), QStringLiteral(":/translations"))) {
        auto metaEnum = QMetaEnum::fromType<QLocale::Language>();
        qDebug() << tr("load qt quick controls translator language %1 failed")
                        .arg(metaEnum.valueToKey(newLanguage));
    }
    qApp->installTranslator(mQtQuickControlsTranslator);
}

LanguageSelector 作为单例注册到 qml:

qmlRegisterSingletonInstance<LanguageSelector>(
    "LanguageSelectors", 1, 0, "LanguageSelector", languageSelector.get());

并像这样连接重新翻译:

const QUrl url(QStringLiteral("qrc:/qml/main.qml"));
QObject::connect(
    &engine, &QQmlApplicationEngine::objectCreated, &app,
    [url](QObject *obj, const QUrl &objUrl) {
        if (!obj && url == objUrl)
            QCoreApplication::exit(-1);
    },
    Qt::QueuedConnection);

QObject::connect(languageSelector.get(), &LanguageSelector::languageChanged,
                 &engine, &QQmlApplicationEngine::retranslate);
engine.load(url);

我在这里做错了吗?或者是否有某种技巧可以告诉按钮获得正确的位置?

标签: c++qtqml

解决方案


推荐阅读