Fundamentos do QCalendarWidget
O QCalendarWidget é um componente robusto do framework Qt que oferece uma interface completa para seleção de datas. Ele vai além de um simples seletor, permitindo navegação mensal intuitiva e alta capacidade de personalização visual.
Para instanciar um calendário básico, o código é direto:
// Instanciação básica em um widget pai
auto *meuCalendario = new QCalendarWidget(this);
meuCalendario->setMinimumSize(400, 300);
meuCalendario->show();
Este componente padrão já entrega funcionalidades como navegação entre meses, realce do dia atual e seleção via clique. No entanto, em aplicações reais, frequentemente precismaos restringir a janela de seleção para evitar entradas inválidas.
Restrição de Datas e Ajustes de Layout
Para limitar o período que o usuário pode selecionar, utilizamos o método setDateRange. Isso é essencail em sistemas de agendamento ou históricos financeiros.
// Definindo limites para o ano de 2025
const QDate dataInicial(2025, 1, 1);
const QDate dataFinal(2025, 12, 31);
meuCalendario->setDateRange(dataInicial, dataFinal);
Além da lógica de datas, a interface pode ser ajustada para melhor legibilidade ou para ocupar menos espaço:
// Ocultar a coluna com o número da semana
meuCalendario->setVerticalHeaderFormat(QCalendarWidget::NoVerticalHeader);
// Configurar o cabeçalho dos dias da semana para exibição curta (ex: Seg, Ter)
meuCalendario->setHorizontalHeaderFormat(QCalendarWidget::ShortDayNames);
// Desativar a barra de navegação superior, se necessário
meuCalendario->setNavigationBarVisible(true);
Customização Visual e Destaque de Datas
Uma das maiores vantagens do QCalendarWidget é a capacidade de estilizar células específicas usando QTextCharFormat. Isso permite, por exemplo, destacar feriados ou dias com eventos pendentes.
// Estilização para finais de semana
QTextCharFormat formatoSabDom;
formatoSabDom.setForeground(Qt::darkRed);
formatoSabDom.setBackground(QColor("#f0f0f0"));
meuCalendario->setWeekdayTextFormat(Qt::Saturday, formatoSabDom);
meuCalendario->setWeekdayTextFormat(Qt::Sunday, formatoSabDom);
// Destacando um dia específico de reunião
QDate dataReuniao(2025, 5, 20);
QTextCharFormat formatoEvento;
formatoEvento.setFontWeight(QFont::Bold);
formatoEvento.setBackground(Qt::cyan);
formatoEvento.setToolTip("Reunião de Planejamento");
meuCalendario->setDateTextFormat(dataReuniao, formatoEvento);
Interação via Sinais e Slots
Para reagir às ações do usuário, o Qt utiliza seu sistema de comunicação por sinais. Os dois eventos mais comuns são a alteração da data selecionada e a navegação entre meses.
// Conectando a mudança de seleção a um método da classe
connect(meuCalendario, &QCalendarWidget::selectionChanged, this, [=]() {
QDate dataSelecionada = meuCalendario->selectedDate();
qDebug() << "Data escolhida:" << dataSelecionada.toString("dd/MM/yyyy");
});
// Detectando quando o usuário muda o mês ou ano exibido
connect(meuCalendario, &QCalendarWidget::currentPageChanged, this, [](int ano, int mes) {
qDebug() << "Navegando para o mês:" << mes << "do ano:" << ano;
});
Renderização Avançada com Customização de Células
Para cenários onde apenas cores não são suficientes, como desenhar ícones ou marcadores personalizados dentro das células, é necessário herdar da classe e sobrescrever o método paintCell. Isso permite um controle total sobre o desenho de cada dia no calendário.
class CalendarioCustomizado : public QCalendarWidget {
protected:
void paintCell(QPainter *painter, const QRect &rect, QDate date) const override {
// Renderização padrão primeiro
QCalendarWidget::paintCell(painter, rect, date);
// Exemplo: Desenhar um pequeno círculo verde se houver tarefas
if (temTarefaNoDia(date)) {
painter->save();
painter->setBrush(Qt::green);
painter->setPen(Qt::NoPen);
painter->drawEllipse(rect.bottomRight() - QPoint(10, 10), 4, 4);
painter->restore();
}
}
private:
bool temTarefaNoDia(QDate date) const {
// Lógica de verificação de banco de dados ou lista
return date.day() % 5 == 0;
}
};