diff options
author | Fabian Kosmale <fabian.kosmale@qt.io> | 2023-01-31 14:19:35 +0100 |
---|---|---|
committer | Qt Cherry-pick Bot <cherrypick_bot@qt-project.org> | 2023-02-08 10:26:10 +0000 |
commit | b097fb6dc6cb13891ab7117c97e6fd6c203d1649 (patch) | |
tree | d6471211b03d6f4139e446b9aadbae07e38e004c | |
parent | 30468f19b93088f4fb73601ecfae2a900c3e1222 (diff) | |
download | qtdoc-b097fb6dc6cb13891ab7117c97e6fd6c203d1649.tar.gz |
qml/i18n: Mention LanguageChange event for C++ types
When QQmlEngine::retranslate refreshed all bindings, that conveniently
worked also for C++ properties. However, that is no longer the case
since Qt 6.2, which only refreshes actual translation bindings.
As bindings cannot know that a C++ setter uses a translation
macro/function, there needs to be a way to inform the engine about them.
Promote event handling as the recommended approach in
C++ types, which aligns with what needs to be done in a Widgets
application.
Task-number: QTBUG-102393
Change-Id: I16b91fcea35331d300fd70756de8819740b5dcb4
Reviewed-by: Leena Miettinen <riitta-leena.miettinen@qt.io>
Reviewed-by: Volker Hilsheimer <volker.hilsheimer@qt.io>
(cherry picked from commit 98504f2c93599c62e5fac7f4b601bd8d04073fba)
Reviewed-by: Qt Cherry-pick Bot <cherrypick_bot@qt-project.org>
-rw-r--r-- | doc/src/internationalization/i18n.qdoc | 100 | ||||
-rw-r--r-- | doc/src/snippets/code/doc_src_i18n.cpp | 52 |
2 files changed, 124 insertions, 28 deletions
diff --git a/doc/src/internationalization/i18n.qdoc b/doc/src/internationalization/i18n.qdoc index cac9fb61..ddc4f0da 100644 --- a/doc/src/internationalization/i18n.qdoc +++ b/doc/src/internationalization/i18n.qdoc @@ -248,6 +248,7 @@ \li \l {Make Keyboard Shortcuts Translatable} \li \l {Use Locale to Extend Localization Features} \li \l {Enable Translation} + \li \l {Prepare for Dynamic Language Changes} \endlist When developing C++ applications, see also @@ -821,6 +822,77 @@ UI display locale at runtime, and install the translator object into the application. + + \section1 Prepare for Dynamic Language Changes + + Both Qt Widgets and Qt Quick use + \l {The Event System}{Qt's event system} to inform classes about + translation changes. + + \l{QEvent::LanguageChange}{LanguageChange} events are posted when you use + the QCoreApplication::installTranslator() function to install a new + translation. Other application components can also force widgets or + QML types derived from the \l Item type to update themselves by posting + \c LanguageChange events to them. + + By default, \c LanguageChange events are propagated to all top-level + windows, and from there they're propagated through the entire tree of + widgets or QML types derived from Item. + + \section2 Qt Widgets: Override changeEvent + + The default event handler for QWidget subclasses responds to the + QEvent::LanguageChange event and calls the \c {changeEvent()} + function when necessary. + + To make Qt widgets aware of changes to the installed QTranslator objects, + reimplement the widget's \l{QWidget::changeEvent()}{changeEvent()} function + to check whether the event is a \l{QEvent::LanguageChange}{LanguageChange} + event and update the text displayed by widgets using the \l{QObject::tr()} + {tr()} function in the usual way. For example: + + \snippet snippets/code/doc_src_i18n.cpp 12 + + To pass on other change events, call the default implementation of the + function. + + The list of installed translators might change in response to a + \l{QEvent::LocaleChange}{LocaleChange} event, or the application might + provide a UI that allows the user to change the current + application language. + + \section2 QML: Override event for Types Derived from Item + For plain QML applications without any custom C++ registered types, + \l {QML: Use QQmlApplicationEngine}{using QQmlApplicationEngine} is enough + to trigger an update of all translation bindings. + + However, if you registered a type derived from QQuickItem, and one of + its properties exposes translated text (or is otherwise language + dependent), override its \l{QObject::event}{event method} and + emit the property's change signal in it (or call + \l{QObjectBindableProperty::notify()}{notify} in case of bindable + properties). For example: + + \snippet snippets/code/doc_src_i18n.cpp 15 + + This ensures that any binding in QML in which the property is used is + reevaluated and takes the language change into account. + + \section2 Generic QObject-derived Classes: Use Event Filters + + Some classes are neither derived from QWidget nor from QQuickItem, but might + still need to handle language change events. In that case, install + \l{Event Filters}{an event filter} on + QCoreApplication. + + \snippet snippets/code/doc_src_i18n.cpp 16 + + This might be necessary when translated strings are provided by the class + that later get displayed in a user interface (for example, a custom + \l{QAbstractItemModel}{item model}), or when the class acts as a container + of Widgets or Quick Items, and is therefore responsible for forwarding the + event to them. + \section1 Additional Considerations for C++ Code The following sections contain more information about using the Qt C++ @@ -831,7 +903,6 @@ \li \l {Define a Translation Context} \li \l {Translate Non-Qt Classes} \li \l {Translate Text That is Outside of a QObject Subclass} - \li \l {Prepare for Dynamic Language Changes} \endlist \section2 Use QString for All User-Visible Text @@ -893,33 +964,6 @@ QCoreApplication::translate() function directly: \snippet snippets/code/doc_src_i18n.cpp 13 - - \section2 Prepare for Dynamic Language Changes - - To make Qt widgets aware of changes to the installed QTranslator objects, - reimplement the widget's \l{QWidget::changeEvent()}{changeEvent()} function - to check whether the event is a \l{QEvent::LanguageChange}{LanguageChange} - event and update the text displayed by widgets using the \l{QObject::tr()} - {tr()} function in the usual way. For example: - - \snippet snippets/code/doc_src_i18n.cpp 12 - - All other change events should be passed on by calling the default - implementation of the function. - - The list of installed translators might change in response to a - \l{QEvent::LocaleChange}{LocaleChange} event, or the application might - provide a UI that allows the user to change the current - application language. - - The default event handler for QWidget subclasses responds to the - QEvent::LanguageChange event, and calls the \c {changeEvent()} - function when necessary. - - \l{QEvent::LanguageChange}{LanguageChange} events are posted when you use - the QCoreApplication::installTranslator() function to install a new - translation. Other application components can also force widgets to update - themselves by posting \c LanguageChange events to them. */ /*! diff --git a/doc/src/snippets/code/doc_src_i18n.cpp b/doc/src/snippets/code/doc_src_i18n.cpp index a258d475..717c387f 100644 --- a/doc/src/snippets/code/doc_src_i18n.cpp +++ b/doc/src/snippets/code/doc_src_i18n.cpp @@ -136,3 +136,55 @@ void same_global_function(LoginWidget *logwid) app.installTranslator(&qtTranslator); } //! [14] + +//! [15] + +class MyItem : public QQuickItem +{ + Q_OJBECT + QML_ELEMENT + + Q_PROPERTY(QString greeting READ greeting NOTIFY greetingChanged) + +public signals: + void greetingChanged(); +public: + QString greeting() const + { + return tr("Hello World!"); + } + + bool event(QEvent *ev) override + { + if (ev->type() == QEvent::LanguageChange) + emit greetingChanged(); + return QQuickItem::event(ev); + } +}; +//! [15] + + +//! [16] +class CustomObject : public QObject +{ + Q_OBJECT + +public: + QList<QQuickItem *> managedItems; + + CustomObject(QOject *parent = nullptr) : QObject(parent) + { + QCoreApplication::instance()->installEventFilter(this); + } + + bool eventFilter(QObject *obj, QEvent *ev) override + { + if (obj == QCoreApplication::instance() && ev->type() == QEvent::LanguageChange) { + for (auto item : std::as_const(managedItems)) + QCoreApplication::sendEvent(item, ev); + // do any further work on reaction, e.g. emit changed signals + } + return false; + } +}; +//! [16] |