No desenvolvimento de interfaces gráficas com Qt, os diálogos (QDialog) são componentes fundamentais para coletar dados, configurar opções ou exibir alertas. Diferente da janela principal (QMainWindow), um diálogo é geralmente uma janela de ciclo de vida curto, projetada para interações específicas.
Conceitos Fundamentais do QDialog
A classe QDialog serve como base para todas as janelas de diálogo. Quando um diálogo é criado, o comportamento do ponteiro parent define sua hierarquia: se for nullptr, o diálogo torna-se uma janela independente no gerenciador de janelas do sistema operacional; caso contrário, ele se comporta como uma subjanela centralizada em relação ao seu pai.
Existem dois tipos principais de diálogos:
- Modais: Bloqueiam a interação com outras janelas da mesma aplicação até que o diálogo seja fechado.
- Não Modais: Permitem que o usuário interaja com o restante da aplicação enquanto o diálogo permanece aberto.
Diálogos Padrão do Qt
O Qt fornece uma série de classes prontas para tarefas comuns, evitando que o desenvolvedor precise reinventar interfaces básicas:
QColorDialog: Seleção de cores.QFileDialog: Manipulação de arquivos e diretórios.QFontDialog: Escolha de tipografia.QInputDialog: Entrada simples de texto, números ou itens.QMessageBox: Exibição de mensagens informativas ou perguntas.
Veja um exemplo prático utilizando o diálogo de arquivos para selecionar múltiplos itens:
// Configuração de um botão para abrir o seletor de arquivos
auto *btnArquivos = new QPushButton("Abrir Arquivos", this);
btnArquivos->setGeometry(200, 50, 150, 40);
connect(btnArquivos, &QPushButton::clicked, this, [this]() {
QStringList listaArquivos = QFileDialog::getOpenFileNames(
this,
"Selecione um ou mais arquivos",
"/home",
"Imagens (*.png *.jpg);;Todos os arquivos (*.*)"
);
for (const QString &caminho : listaArquivos) {
qDebug() << "Arquivo selecionado:" << caminho;
}
});
Implementação de Diálogos Modais
Para criar um diálogo modal, utiliza-se o método exec(). Este método entra em um loop de eventos próprio, pausando a execução do código subsequente até o fechamento da janela.
connect(btnModal, &QPushButton::clicked, this, [this]() {
QDialog janelaModal(this);
janelaModal.setWindowTitle("Configurações");
janelaModal.setMinimumSize(300, 200);
// O código abaixo aguarda o fechamento da janela
if (janelaModal.exec() == QDialog::Accepted) {
qDebug() << "Usuário confirmou a operação.";
}
});
Diálogos Não Modais e Gestão de Memória
Ao trabalahr com diálogos não modais usando show(), é necessário ter cuidado com o escopo da variável. Se o objeto for criado na pilha (stack), ele será destruído assim que o escopo da função terminar, fazendo a janela "piscar" e desapareecr.
A solução recomendada é a alocação dinâmica no heap combinada com o atributo Qt::WA_DeleteOnClose, que garante a liberação da memória automaticamente quando a janela for fechada:
connect(btnNaoModal, &QPushButton::clicked, this, [this]() {
QDialog *janelaLivre = new QDialog(this);
janelaLivre->setAttribute(Qt::WA_DeleteOnClose);
janelaLivre->setWindowTitle("Painel Flutuante");
janelaLivre->resize(400, 300);
janelaLivre->show(); // Não bloqueia a execução
});
Uso do QMessageBox
O QMessageBox é a forma mais rápida de interagir com o usuário para validações ou avisos. Ele oferece métodos estáticos para diferentes propósitos:
// Exemplo de diálogo de informação
QMessageBox::information(this, "Sucesso", "O processo foi concluído corretamente.");
// Exemplo de diálogo de pergunta com botões customizados
int resposta = QMessageBox::question(this, "Confirmar Exclusão",
"Deseja realmente apagar o registro?",
QMessageBox::Yes | QMessageBox::No);
if (resposta == QMessageBox::Yes) {
qDebug() << "Ação de exclusão executada.";
} else {
qDebug() << "Ação cancelada.";
}