summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorFabian Kosmale <fabian.kosmale@qt.io>2023-01-31 14:19:35 +0100
committerQt Cherry-pick Bot <cherrypick_bot@qt-project.org>2023-02-08 10:26:10 +0000
commitb097fb6dc6cb13891ab7117c97e6fd6c203d1649 (patch)
treed6471211b03d6f4139e446b9aadbae07e38e004c
parent30468f19b93088f4fb73601ecfae2a900c3e1222 (diff)
downloadqtdoc-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.qdoc100
-rw-r--r--doc/src/snippets/code/doc_src_i18n.cpp52
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]