Traduzioni¶
Ogni stringa visibile all'utente che un plugin mostra dev'essere traducibile, con
cataloghi per tutte e quindici le lingue supportate — en, pl, de, fr,
es, pt_PT, pt_BR, nl, sv, nb, da, fi, it, cs, sk — prima che
il plugin possa dirsi finito. È lo stesso metro dei test.
Cataloghi¶
Ogni plugin che abbia una qualsiasi stringa porta un catalogo .ts per lingua
nella propria cartella Translations/:
Collegali alla compilazione tramite mte_add_plugin:
mte_add_plugin(NAME MyPlugin
SOURCES Src/MyPlugin.cpp
TRANSLATIONS
Translations/MyPlugin_en.ts
Translations/MyPlugin_pl.ts
Translations/MyPlugin_de.ts
Translations/MyPlugin_fr.ts
)
La compilazione esegue lrelease per predisporre i file .qm;
TranslationManager li carica per nome di catalogo a tempo di esecuzione (i
cataloghi dei plugin sotto Plugins/Translations/<Plugin>/).
Marcare le stringhe per la traduzione¶
- Preferisci
QObject::tr(...)(contesto = la classe) per le normali stringhe dell'interfaccia. - L'ausilio
tr_()avvolgeQCoreApplication::translate("<Context>", s)per le stringhe fuori da unQObject.
tr_() è invisibile a lupdate
lupdate non riesce a risolvere il contesto dentro tr_(), quindi quei
cataloghi si mantengono a mano. Mantieni il testo <source> identico byte
per byte alla stringa a tempo di esecuzione, altrimenti la traduzione
silenziosamente non verrà applicata.
Seguire un cambio di lingua mentre una pagina è aperta¶
L'utente può cambiare la lingua dell'interfaccia in Preferenze ▸ Generale
senza riavviare. Qt invia allora un QEvent::LanguageChange a ogni widget — ma un
albero di widget le cui stringhe sono state impostate una volta sola, nel codice
che lo ha costruito, conserva la lingua precedente finché la finestra non viene
chiusa e riaperta.
PluginApi/Qt/Retranslator.h se ne occupa senza costringerti a scrivere ogni
stringa due volte. Registra come ciascuna stringa è stata prodotta e riproduce
la registrazione quando la lingua cambia:
#include <PluginApi/Qt/Retranslator.h>
QWidget* MyPage::createWidget(QWidget* parent)
{
auto* page = new QWidget(parent);
auto& rt = MTE::plugin::Retranslator::installOn(page);
m_watch = new QCheckBox(page);
rt.add([this] { m_watch->setText(tr_("Watch open files")); });
m_size = new QSpinBox(page);
rt.row(form, m_size, [] { return tr_("Font size:"); }); // QFormLayout caption
return page;
}
add()esegue la sua lambda immediatamente, così il punto di chiamata si legge esattamente come la riga «imposta il testo» che sostituisce, e ogni stringa compare comunque una sola volta nei tuoi sorgenti.row()fa lo stesso per la didascalia di unQFormLayout, che altrimenti diventa irraggiungibile una volta cheaddRow()l'ha consumata.installOn()è idempotente per ciascun widget; il registratore è figlio di quel widget e muore con esso. Se la tua pagina può sopravvivere a un widget che hai catturato, conservalo in unQPointer.
Come PluginApi/Qt/ISettingsPage.h, questa è un'intestazione Qt opzionale:
includila solo da codice che già costruisce dei QWidget (richiede
Qt6::Widgets). La parte di PluginApi priva di Qt non ne è toccata.
Che cosa non viene tradotto¶
Due cose restano, per scelta, nella lingua in cui il loro autore le ha scritte:
- Il
namee ladescriptiondel tuo plugin daplugin.json, come mostrati in Preferenze ▸ Estensioni. Il manifest viene letto prima che il plugin sia caricato — è questo che permette alla pagina di elencare i plugin disabilitati o compilati per un'altra versione dell'API — quindi a quel punto non esiste alcun catalogo in cui cercarli. - Le etichette di una pagina delle impostazioni o di un pannello ancorabile dichiarativi (Python). Sono dati che il tuo worker invia all'host, non stringhe che l'host possa risolvere rispetto a un catalogo.
Tutto ciò che un plugin registra a tempo di esecuzione — titoli dei comandi, voci di menu, titoli dei pannelli, didascalie delle pagine delle impostazioni — viene tradotto nel modo consueto descritto sopra.
Tre di quelle stringhe le cerca l'host, non il tuo codice, nel contesto
condiviso PluginMenus: ogni segmento di un menuPath, ogni title di comando e
la category del comando. Distribuisci tutte e tre come voci <source> nel
contesto PluginMenus dei tuoi cataloghi. La categoria è ciò che l'utente legge
nella colonna Categoria di Preferenze ▸ Scorciatoie; quando manca dal
catalogo, la colonna mostra la parola inglese grezza accanto alle righe tradotte
del nucleo. Una categoria che è anche un titolo di menu (Search, Encoding)
condivide una sola voce: conserva al suo interno il mnemonico & per il menu,
l'host lo rimuove per la colonna.
Definizione di «finito»¶
La localizzazione di un plugin è finita solo quando tutti e quindici i file .ts
esistono, sono collegati e lrelease riporta 0 stringhe non finite.