CustomDialogBox::CustomDialogBox(QWidget *parent)
: QWidget(parent)
{
l_nom = new QLabel(tr("Nom du Client : "));
l_num = new QLabel(tr("Numero de Chambre reservée : "));;
l_adr = new QLabel(tr("Adresse du Client : "));
nom = new QLineEdit;
num = new QLineEdit;
adr = new QLineEdit;
num->setInputMask("009"); // 'ddd' pour ne recevoir que des chiffres, au trop 03
adr->setInputMask("999 999 999");
nom->setMinimumWidth(50);
num->setMinimumWidth(50);
adr->setMinimumWidth(50);
valid = new QPushButton(tr("Ajouter"));
layout = new QFormLayout;
layout->addRow(l_nom, nom);
layout->addRow(l_num, num);
layout->addRow(l_adr, adr);
layout->addRow(valid);
setLayout(layout);
setWindowTitle(tr("Ajout d'une reservation"));
setWindowFlags(Qt::Window | Qt::WindowCloseButtonHint);
connect(valid, SIGNAL(clicked()), this, SLOT(saveOnFile()));
}
Et ma fonction svaeOnFile():
void CustomDialogBox::saveOnFile()
{
QFile fichier("./Data/reserveChm.txt");
if (fichier.open(QIODevice::WriteOnly | QIODevice::Text | QFile::Append)) {
QTextStream out(&fichier);
out << nom->text() << "|"
<< num->text() << "|"
<< QDateTime::currentDateTime().toString() << "|"
<< adr->text() << "\n";
}
else{
QMessageBox::critical(this, tr("Problème rencontré"), tr("Une erreur est survenu lors de l'ouverture du fichier"));
}
}
Je tiens a rappeler que le code est tel qu'il etait il y'a deux ans, je suis vraiment ouvert a des moyens pour son amelioration.
Je veux que la fonction saveOnFile() s'execute uniquement si les QLineEdit sont tous remplis. Je voulais mettre une condition avant l'enregistrement directement dans saveOnFile qui sera du genre:
if (nom->text()->length() == 0 || num->text()->length() == 0 || ...)
QMessageBox::critical(this, tr("Enregistrement impossible"), tr("Veuillez remplir tous les champs de ce formulaire");
Mais je veux que ce soit fait dans le CustomWidget et non dans ma fonction. Et si possible que l'application affiche elle meme le message mais pas que moi je le fasse. Vous avez donc une idee pour obliger ce remplissage avant que le bouton ne soit meme disponible (donc il sera grisé au debut) ?
Je suis pas de cours en Qt, l'IDE meme QtCreator a une riche documentation et je me sers juste de ca. Si vous avez des cours en "francais" dessus je suis aussi partant.
Ben, selon le bon vieux principe du SRP (Single Responsability Principle), tu devrais ajouter une fonction membre à ta boite de dialogque custom.
Tu pourrais l'appeler, pour que les gens puissent comprendre ce qu'elle fait, par exemple checkIt ou pouquoi pas checkFields, voire même isDialogReadyToSave et il serait sans doute pas mal qu'elle renvoie un booléen dont la valeur serait à true si tous les champs sont remplis et à false dans le cas contraire.
Elle pourrait donc tout à fait ressembler à quelque chose comme
bool CustomDialogBox::checkIt(){
/* je vais, volontairement, passer toutes les étapes en
* revue, pour qu'il ne puisse y avoir aucun doute sur ce
* qui est fait
*/
bool result{true}; // on considère de base que tout est correct
if(adr.text().empty()) // si l'adresse est vide
result = false; // ca va pas le faire
if(nom.text().empty()) // si le nom est vide
result = false; // ca le fait pas non plus
if(num.tex().empty()) // et enfin, si le numéro est vide
result = false; // ca n'ira pas d'avantage
return result;
}
Tu peux parfaitement déclarer cette fonction dans l'accessibilité privée, car il n'y a clairement que ton dialogue custom (et plus précisément la fonction saveOnFile) qui devra y accéder... Il n'y a donc pas besoin de l'exposer "au tout venant"
L'idée de cette fonction est toute simple dans le principe: on part du principe que tout est correct ... jusqu'à preuve du contraire.
Si l'on croise la preuve que "quelque chose n'est pas correct", alors, result vaudra automatiquement faux, et nous saurons que l'enregistrement ne peut pas se faire
Puis, une fois que tu as cette fantastique manière de savoir si tous les champs sont prêts à être enregistrer, tu pourra modifier ta fonction saveOnFile de manière à ce qu'elle tienne compte de te "check", sous une forme proche de
oid CustomDialogBox::saveOnFile()
{
if(checkIt()){ // si le check est validé
QFile fichier("./Data/reserveChm.txt");
if (fichier.open(QIODevice::WriteOnly |
QIODevice::Text | QFile::Append)) {
QTextStream out(&fichier);
out << nom->text() << "|"
<< num->text() << "|"
<< QDateTime::currentDateTime().toString() << "|"
<< adr->text() << "\n";
}
else{
QMessageBox::critical(this, tr("Problème rencontré"), tr("Une erreur est survenu lors de l'ouverture du fichier"));
}
} // Si tu y tiens, tu peux rajouter un message d'erreur indiquant qu'il faut remplir tous les champs<
e:se{
QMessageBox::critical(this, tr("Données manquantes"),tr("L'enregistrement n'a pas été fait car des données sont manquantes"));
}
Et le tour sera joué
NOTA : nous pourrions même aller plus loin dans le respect du SRP en nous disant que la fonction saveOnFile ne fait que mettre le check (la fonction checkIt) et la possibilité de réellement effectuer la sauvegarde (qui prendrait la forme d'une fonction nommée reallySaveOnFile, par exemple) pour que cette dernière n'ai vraiment à s'inquiéter de la possibilité "physique" d'enregistrement.
Ainsi, le code d'origine de ta fonction saveOnFile deviendrait le code de la fonction reallySaveOnFile (qui pourrait elle aussi être déclarée dans l'accessibilité privée), sous la forme de
void CustomDialogBox::reallySaveOnFile()
{
QFile fichier("./Data/reserveChm.txt");
if (fichier.open(QIODevice::WriteOnly | QIODevice::Text | QFile::Append)) {
QTextStream out(&fichier);
out << nom->text() << "|"
<< num->text() << "|"
<< QDateTime::currentDateTime().toString() << "|"
<< adr->text() << "\n";
}
else{
QMessageBox::critical(this, tr("Problème rencontré"), tr("Une erreur est survenu lors de l'ouverture du fichier"));
}
}
et le code de ta fonction saveOnFile prendrait la forme de
void CustomDialogBox::saveOnFile()
{
if(checkIt()) // si le check et concluant
reallySaveOnFile(); // on essaye effectivement
// d'enregistrer les données
else // tu ajoute ce message ... ou non, selon tes gouts
QMessageBox::critical(this, tr("Données manquantes"),tr("L'enregistrement n'a pas été fait car des données sont manquantes"));
}
L'idée derrière tout cet exercice est de prendre simplement l'habitude de ne t'inquiéter d'un seul problème à la fois. Tu peux te le permettre ici car tout sera de toutes manières "piloté" par l'interface graphique, et que, même s'il devait y avoir une légère perte de performances du fait des différents appels de fonctions (ce qui devrait encore être prouvé ) le temps de réaction de l'utilisateur ferait que cela ne change au final absolument rien , car on a quoi? peut être 0.0003 secondes de délais du à l'appel d'une fonction supplémentaire? Comparés au 0.2 secondes qui seront de toutes manières indispensable pour que le disque dur trouve l'endroit où l'écriture pourra se faire et pour qu'il la fasse effectivement, cela ne peut pas avoir d'influence néfaste
D'un autre coté, je dois avouer que cette deuxième approche est peut-être un peu exagérée et "jusqu'au bouliste", car elle n'apporte pas grand chose à la première solution présentée... Quoi que ... ?
EDIT:
Note au passage que l'on pourrait améliorer la logique de la fonction checkIt en lui donnant la forme de
car l'opérateur && (ainsi que l'opérateur || ) est ce que l'on appelle un opérateur "optimisé", c'est à dire qu'il ne va évaluer l'opérande de droite que si le résultat final peut encore être modifié.
Cela signifie que, dans le cas présent, le test va s'assurer que adr n'est pas vide et que nom ne sera testé que... si adr n'est pas vide (car, à ce moment là, le "status" de nom pourra encore changer la donne) et que, de même, num ne sera testé que si nom (et donc, forcément, adr) n'est pas vide.
Autrement dit, cela permet de s'assurer qu'il n'y aura -- au pire -- jamais qu'un seul champs vide de testé, alors que la première version de la fonction les vérifiera tous.
Mais, encore une fois, dans ce cadre bien précis, tu ne verras sans doute absolument aucun avantage à utiliser cette notation, car le temps du test est tellement faible par rapport au reste que tu n'en verra pas la différence
- Edité par koala01 13 mai 2022 à 16:11:28
Ce qui se conçoit bien s'énonce clairement. Et les mots pour le dire viennent aisément.Mon nouveau livre : Coder efficacement - Bonnes pratiques et erreurs à éviter (en C++)Avant de faire ce que tu ne pourras défaire, penses à tout ce que tu ne pourras plus faire une fois que tu l'auras fait
Et pour "Et si possible que l'application affiche elle meme le message mais pas que moi je le fasse." je compte utiliser QToolTip, a force de fouiller la doc j'ai trouvé. J'aurai qu'a définir un pour chaque champ et l'afficher sur les champs vides a la "soumission" sans faire appel a QMessageBox.
Autre chose, je pense que c'est pas au dialog de faire l'enregistrement, c'est au code appellant.
CustomDialogBox box;
box.open();
if (box.answer() == ok)
save(box.infos());
CustomDialogBox est un nom bof bof, pas tres explicite.
Et a mon avis, si tu fais ca, cela justifie de créer un custom widget pour le texte + le line edit + le message d'erreur.
- Edité par gbdivers il y a environ 3 heures
Je connais pas vraiment cette syntaxe, je precise que c'etait pas vraiment une QDialog. Je vais donc modifier sa structure pour cela.
gbdivers a écrit:
Un dialog qui ouvre un autre dialog, je dirais que c'est bof en termes d'UI.
Mettre en rouge les champs qui ne sont pas remplis + un message pour dire que leur remplissage est obligatoire me semble mieux.
j'ai aucune idee de comment on fait. Mais je vais chercher apres etre passé de QWidget a QDialog.
Edit:
J'ai lu un peu et voila:
if (fieldsAreValid()){ // C'est pareil checkIt() qui est plus haut
}
else {
//QMessageBox::critical(this, tr("Enregistrement impossible"), tr("Tous les champs doivent etre remplis"));
for (auto &var : getInvalidFields()) { // cette fonction renvoie les champs non remplis
var->setStyleSheet("border: 2px solid red");
var->setToolTip("Veuillez remplir ce champ"); // Je voulais afficher un petit texte avec mais je comprends toujours pas le fonctionnement de ToolTip, rien ne s'affiche
}
}
- Edité par Asmitta 13 mai 2022 à 22:05:12
Empecher la validation d'un QDialog
× Après avoir cliqué sur "Répondre" vous serez invité à vous connecter pour que votre message soit publié.
× Attention, ce sujet est très ancien. Le déterrer n'est pas forcément approprié. Nous te conseillons de créer un nouveau sujet pour poser ta question.
Discord NaN. Mon site.