Por que acessibilidade não é coisa de "fracos", mas sim qualidade de código
\n\nQuando escrevemos em C++, estamos acostumados a pensar em desempenho, memória e velocidade. Mas há outro aspecto que muitas vezes é negligenciado — acessibilidade. Não é apenas um termo da moda do mundo do desenvolvimento web. Em C++, a acessibilidade de aplicações é a possibilidade de pessoas com deficiências (visuais, auditivas, motoras) usarem seu software em igualdade de condições com os outros.
\n\nImagine: você criou um editor gráfico incrível ou um utilitário de console. Mas se ele não for lido por um screen reader ou não puder ser controlado pelo teclado — você está excluindo 15–20% dos usuários. Além disso, a acessibilidade é frequentemente uma exigência legal (por exemplo, nos EUA — Section 508, na Europa — EN 301 549).
\n\nNeste artigo, vamos abordar como implementar a11y best practices (a11y é a abreviatura numérica de accessibility) em projetos C++, sem sacrificar o desempenho. Vamos nessa!
\n\nPor onde começar: princípios básicos do código inclusivo
\n\nAntes de mergulhar no código, lembre-se dos três pilares:
\n\n- \n
- Perceptibilidade — a informação deve estar disponível através de pelo menos um sentido (visão, audição, tato). \n
- Operabilidade — a interface deve funcionar com teclado, voz ou interruptores. \n
- Compreensibilidade — o comportamento dos elementos é previsível, os erros são compreensíveis. \n
Em C++, isso é especialmente importante porque frequentemente trabalhamos com APIs de baixo nível, onde a semântica se perde. Por exemplo, ao desenhar um botão via OpenGL, você não obtém suporte automático para screen readers — é necessário adicioná-lo manualmente.
\n\nMarcação semântica em GUI C++: Qt e além
\n\nA maneira mais comum de adicionar acessibilidade em C++ é usar o framework Qt. Ele possui suporte integrado através do QAccessibleInterface. Mas mesmo se você estiver escrevendo em WinAPI puro, existe o IAccessible.
Exemplo: tornando um botão acessível
\n\nSuponha que você tenha um botão personalizado, desenhado via QPainter. Sem acessibilidade, o screen reader verá apenas um "retângulo". Vamos corrigir:
\n\n#include <QAccessible>\n#include <QAccessibleWidget>\n#include <QPushButton>\n\nclass AccessibleButton : public QAccessibleWidget {\npublic:\n explicit AccessibleButton(QWidget* widget)\n : QAccessibleWidget(widget, QAccessible::Button) {}\n\n QString text(QAccessible::Text t) const override {\n if (t == QAccessible::Name) {\n auto* btn = qobject_cast<QPushButton*>(widget());\n return btn ? btn->text() : QString();\n }\n return QAccessibleWidget::text(t);\n }\n};\n\n// Uso:\nQPushButton* btn = new QPushButton("Enviar");\nQAccessible::registerAccessibleFactory(\n [](QObject* obj) -> QAccessibleInterface* {\n if (auto* btn = qobject_cast<QPushButton*>(obj)) {\n return new AccessibleButton(btn);\n }\n return nullptr;\n }\n);\n\nAgora o screen reader lerá "Enviar, botão". Mágica? Não, apenas código inclusivo.
\n\nAcessibilidade em aplicações de console C++
\n\nPode parecer que o console é coisa do passado. Mas muitos utilitários, pipelines de CI/CD e aplicações servidoras funcionam exatamente no terminal. Como torná-los acessíveis?
\n\nSaída correta para screen readers
\n\nO screen reader (por exemplo, NVDA, JAWS) lê o console linha por linha. Se você exibir uma tabela com caracteres ASCII — isso é um pesadelo. É melhor usar saída estruturada:
\n\n#include <iostream>\n#include <string>\n#include <vector>\n\nstruct User {\n std::string name;\n int age;\n};\n\nvoid printAccessibleTable(const std::vector<User>& users) {\n // Amigável para screen reader: primeiro o cabeçalho, depois os dados\n std::cout << "Tabela de usuários:" << std::endl;\n for (const auto&