Traduções¶
Toda cadeia visível ao usuário que um plugin exibe precisa ser traduzível, com
catálogos para os quinze idiomas suportados — en, pl, de, fr, es,
pt_PT, pt_BR, nl, sv, nb, da, fi, it, cs, sk — antes de o
plugin ser considerado pronto. Esse é o mesmo padrão dos testes.
Catálogos¶
Cada plugin que tem alguma cadeia carrega um catálogo .ts por idioma na pasta
Translations/ dele:
Conecte-os à compilação via 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
)
A compilação executa o lrelease para preparar os arquivos .qm; o
TranslationManager os carrega por nome de catálogo em tempo de execução (os
catálogos de plugin ficam sob Plugins/Translations/<Plugin>/).
Marcando cadeias para tradução¶
- Prefira
QObject::tr(...)(contexto = a classe) para as cadeias de interface normais. - O auxiliar
tr_()envolveQCoreApplication::translate("<Context>", s)para cadeias fora de umQObject.
tr_() é invisível para o lupdate
O lupdate não consegue resolver o contexto dentro de tr_(), então esses
catálogos são mantidos à mão. Mantenha o texto de <source> idêntico byte a
byte à cadeia em tempo de execução, ou a tradução simplesmente não se aplica,
sem avisar.
Acompanhando uma mudança de idioma com uma página aberta¶
O usuário pode mudar o idioma da interface em Preferências ▸ Geral sem
reiniciar. O Qt então envia QEvent::LanguageChange a todos os widgets — mas uma
árvore de widgets cujas cadeias foram definidas uma única vez, no código que a
construiu, mantém o idioma antigo até a caixa de diálogo ser fechada e reaberta.
O PluginApi/Qt/Retranslator.h cuida disso sem escrever cada cadeia duas vezes.
Ele registra como cada cadeia foi produzida e reproduz o registro quando o idioma
muda:
#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()executa a lambda dele imediatamente, então o ponto de chamada se lê exatamente como a linha de "defina o texto" que ele substitui, e cada cadeia ainda aparece uma vez no seu código-fonte.row()faz o mesmo para um rótulo deQFormLayout, que de outro modo fica inalcançável depois que oaddRow()o consumiu.installOn()é idempotente por widget; o gravador é filho daquele widget e morre com ele. Se sua página pode sobreviver a um widget que você capturou, guarde-o em umQPointer.
Como o PluginApi/Qt/ISettingsPage.h, este é um cabeçalho opcional do Qt:
inclua-o apenas a partir de código que já constrói QWidgets (ele precisa de
Qt6::Widgets). A parte do PluginApi livre de Qt não é afetada.
O que não é traduzido¶
Duas coisas permanecem no idioma em que o autor as escreveu, por design:
- O
namee adescriptiondo seu plugin, doplugin.json, como exibidos em Preferências ▸ Plug-ins. O manifesto é lido antes de o plugin ser carregado — é isso que permite que a página liste plugins desativados ou compilados contra outra versão da API — então não há catálogo em que procurá-los naquele momento. - Os rótulos de uma página de configurações ou painel acoplável declarativo (de Python). Eles são dados que o seu trabalhador envia ao host, não cadeias que o host possa resolver contra um catálogo.
Tudo o que um plugin registra em tempo de execução — títulos de comandos, entradas de menu, títulos de painéis, rótulos de páginas de configurações — é traduzido da forma comum descrita acima.
Três dessas cadeias são procuradas pelo host, não pelo seu código, no contexto
compartilhado PluginMenus: cada segmento de um menuPath, cada title de
comando e a category do comando. Distribua as três como entradas <source> no
contexto PluginMenus dos seus próprios catálogos. A categoria é o que o usuário
lê na coluna Categoria de Preferências ▸ Atalhos; quando ela falta no
catálogo, a coluna mostra a palavra inglesa crua ao lado das linhas traduzidas do
núcleo. Uma categoria que também é um título de menu (Search, Encoding)
compartilha uma única entrada: mantenha nela o mnemônico & para o menu, o host o
remove para a coluna.
Definição de pronto¶
A localização de um plugin só está pronta quando os quinze arquivos .ts existem,
estão conectados, e o lrelease reporta 0 cadeias não terminadas.