[Edit : J'ai trouvé, je m'impressionne, quelle puissance, j'avais mis un delete sur le pointeur, évidemment il est assez difficile d'accéder à un élément supprimé dans un tableau... merci quand même ]
Bonzouar...
J'fais encore une fois appel à vous, pour des tableaux de pointeurs de structure cette fois, c'est la première fois que je fais un truc pareil, et ça se voit au résultat que ça donne (un joli plantage du programme).
J'utilise Qt, vector pour les tableaux (j'ai lu le tutoriel de Nanoc sur std::vector).
Tout compile mais le programme plante (la fameuse "opération non conforme" que mène chaque jour Windows).
Je vous explique vite fait le but, j'ai une fenêtre qui est censée gérer les fichiers à inclure pour générer le code correspondant. Pour ça, on a un "tableau" (pas vraiment un tableau, mais un layout grille quoi) avec des lignes qui s'ajoutent quand on appuie sur le bouton "Ajouter".
Chaque ligne contient un CheckBox de sélection (pour pouvoir supprimer les lignes sélectionnées, pas encore opérationnel) + un champ de texte pour le nom, + une ComboBox avec deux choix (interne ou externe, sachant que interne correspond à "fichier.h" et externe à <fichier>)
Alors le code...
Le header intéressant :
#ifndef DEF_INCLUSIONS
#define DEF_INCLUSIONS
#include <QtGui>
#include <vector>
#include "global.h"
class Inclusions : public QWidget
{
Q_OBJECT
public:
Inclusions();
QString getNom(int numero);
public slots:
void creernew();
private:
struct Inclus; //Structure pour les fichiers à inclure.
std::vector<Inclus*> tableInclus; //Tableau de pointeurs de fichiers à inclure.
QPushButton *ok, *creer, *supprimer;
QGroupBox *tableau;
QGridLayout *LAYtableau; //Pour ranger les boutons des différents fichiers
QGroupBox *boutons;
QHBoxLayout *LAYboutons; //Pour ranger les boutons de la fenêtre
QVBoxLayout *LAYvertical; //Pour organiser les deux groupbox
QLabel *lselect, *lnom, *ltype; //1ere ligne du tableau, indique ce que représentent les widgets.
int derniereLigne; //Dernière ligne du tableau (0 par défaut)
};
#endif
Ensuite, le fichier cpp correspondant (j'ai enlevé le constructeur, qui ne concerne pas le problème) :
#include "inclusions.h"
#include "global.h"
struct Inclusions::Inclus
{
//Boutons : Chaque fichier a un coche de sélection, une barre de nom et un choix de type.
QCheckBox *iselect;
QLineEdit *inom;
QComboBox *itype; //Avec choix interne/externe. Par défaut externe.
//Variables
QString nom; //"" par défaut
bool selected; //False par défaut
bool interne; //False par défaut
//Si le fichier est interne, on rajoute .h et on entoure de " "
//Sinon, il est externe, et on entoure de < >
};
QString Inclusions::getNom(int numero)
{
return (tableInclus[numero]->nom);
}
void Inclusions::creernew()
{
Inclus* pointeur = NULL;
pointeur = new Inclus;
pointeur->iselect = new QCheckBox;
pointeur->inom = new QLineEdit;
pointeur->itype = new QComboBox;
pointeur->itype->setEditable(false);
pointeur->itype->addItem("Externe");
pointeur->itype->addItem("Interne");
pointeur->nom = "Helloworld"; //J'initialise à "Helloworld" pour tester.
pointeur->interne = false;
pointeur->selected = false;
LAYtableau->addWidget(pointeur->iselect, derniereLigne+1,0);
LAYtableau->addWidget(pointeur->inom, derniereLigne+1,1);
LAYtableau->addWidget(pointeur->itype, derniereLigne+1,2);
tableInclus.push_back(pointeur);
delete pointeur;
/* J'avais essayé en ajoutant directement un pointeur dans le tableau et en le modifiant, mais ça ne compilait pas
tableInclus[derniereLigne]->nom = "";
tableInclus[derniereLigne]->interne = false;
tableInclus[derniereLigne]->selected = false;
tableInclus[derniereLigne]->iselect = new QCheckBox;
tableInclus[derniereLigne]->inom = new QLineEdit;
tableInclus[derniereLigne]->itype = new QComboBox;
tableInclus[derniereLigne]->itype->setEditable(false); //currentText() pour get.
tableInclus[derniereLigne]->itype->addItem("Externe");
tableInclus[derniereLigne]->itype->addItem("Interne");
LAYtableau->addWidget(tableInclus[derniereLigne]->iselect, derniereLigne+1, 0);
LAYtableau->addWidget(tableInclus[derniereLigne]->inom, derniereLigne+1, 1);
LAYtableau->addWidget(tableInclus[derniereLigne]->itype, derniereLigne+1, 2);
*/
derniereLigne ++;
}
Tout ça, ça marche à priori, puisque les lignes se rajoutent comme prévu, même si j'ai bien peur que le tableau ne prenne pas le pointeur correctement, puisque sans détruire le pointeur et sans le tableau, on obtient le même résultat.
Je crée dans un autre fichier (qui n'a aucun rapport avec le problème) l'objet FInclude de classe Inclusions.
Le problème se pose quand je teste dans ce fichier le code suivant (codecpp est un QString):
codecpp += FInclude.getNom(1);
(C'est juste un code de test hein, je fais en sorte que le tableau contienne assez d'éléments pour pouvoir utiliser la case 1)
Normalement, ça devrait ajouter le nom ("Helloworld") dans codecpp, mais non, ça plante
En même temps je manque d'expérience avec les pointeurs et les tableaux, je gère sûrement mal ça quelque part, mais je ne suis pas capable de comprendre où ça cloche...
Si y'avait éventuellement moyen de faire autrement qu'avec un tableau de pointeurs de structures, ça m'arrangerait, c'est un peu trop complexe pour moi, cette histoire !
Si vous voulez compiler pour constater, essayer des choses, je donne le code complet en secret :
#include "fenetre.h"
#include "dialogue.h"
#include "inclusions.h"
#include "global.h"
Fenetre::Fenetre() : QWidget()
{
//PushButtons
m_quitter = new QPushButton("Quitter");
m_generer = new QPushButton("Générer !");
m_menuinclude = new QPushButton("Inclusions...");
m_menuattributs = new QPushButton("Attributs...");
//CheckBoxes
m_inclusions = new QCheckBox("Protéger contre les &inclusions multiples");
m_constructeur = new QCheckBox("Générer un &constructeur par défaut");
m_destructeur = new QCheckBox("Générer un &destructeur par défaut");
//Labels
m_nom = new QLabel("Nom de la classe :");
m_classeMere = new QLabel("Classe mère :");
m_auteur = new QLabel("Auteur :");
m_date = new QLabel("Date de création :");
m_description = new QLabel("Description :");
//Inputs
m_idate = new QDateEdit;
m_iauteur = new QLineEdit;
m_inom = new QLineEdit;
m_imere = new QLineEdit;
m_idescription = new QTextEdit;
m_idescription->setFixedSize(150,60);
//GroupBoxes
m_boutons = new QGroupBox;
m_boutons->setFlat(true);
m_horizontal = new QHBoxLayout;
m_horizontal->addWidget(m_generer);
m_horizontal->addWidget(m_quitter);
m_horizontal->addWidget(m_menuinclude);
m_horizontal->addWidget(m_menuattributs);
m_boutons->setLayout(m_horizontal);
m_defClasse = new QGroupBox("Définition de la classe");
m_LAYdef = new QGridLayout;
m_LAYdef->addWidget(m_nom, 0, 0);
m_LAYdef->addWidget(m_classeMere, 1, 0);
m_LAYdef->addWidget(m_inom, 0, 1, 1, 3); //3 cases de largeur
m_LAYdef->addWidget(m_imere, 1, 1, 1, 3); //Idem
m_defClasse->setLayout(m_LAYdef); //C'est dans la boîte !
m_options = new QGroupBox("Options");
m_LAYoptions = new QVBoxLayout;
m_LAYoptions->addWidget(m_inclusions);
m_LAYoptions->addWidget(m_constructeur);
m_LAYoptions->addWidget(m_destructeur);
m_options->setLayout(m_LAYoptions); //C'est dans la boîte !
m_commentaires = new QGroupBox("Commentaires");
m_commentaires->setCheckable(true);
m_LAYcommentaires = new QGridLayout;
m_LAYcommentaires->addWidget(m_auteur, 0, 0);
m_LAYcommentaires->addWidget(m_date, 1, 0);
m_LAYcommentaires->addWidget(m_description, 2, 0);
m_LAYcommentaires->addWidget(m_iauteur, 0, 1, 1, 3); //Largeur = 3
m_LAYcommentaires->addWidget(m_idate, 1, 1, 1, 3); //Idem
m_LAYcommentaires->addWidget(m_idescription, 2, 1, 1, 3); //Itou
m_commentaires->setLayout(m_LAYcommentaires); //C'est dans la boîîîte !
//Layout vertical principal
m_vertical = new QVBoxLayout(this);
m_vertical->addWidget(m_defClasse);
m_vertical->addWidget(m_options);
m_vertical->addWidget(m_commentaires);
m_vertical->addWidget(m_boutons);
//Connexions signal/slot
QObject::connect(m_quitter, SIGNAL(clicked()), qApp, SLOT(quit()));
QObject::connect(m_generer, SIGNAL(clicked()), this, SLOT(generer()));
QObject::connect(m_menuinclude, SIGNAL(clicked()), this, SLOT(menuIn()));
}
//Slot, gère les erreurs de génération, la génération du code, l'ouverture de la fenêtre de code.
void Fenetre::generer()
{
bool dejafait = false;
bool touvabien = true; //Change en false si une erreur intervient (on ne génèrera alors pas)
QString codeh = "", codecpp = "";
if ((m_inom->text().isEmpty()) == true) //Si la classe n'a pas de nom
{
touvabien = false;
QMessageBox::warning(this, "Erreur", "Donnez un nom à la classe");
}
if (touvabien)
{//On génère le code (utiliser bool isChecked() pour les cases cochables, text() pour les inputs)
//On génère les commentaires
if (m_commentaires->isChecked() == true) //Si on ajoute des commentaires
{
codeh += "/* \n";
if ((m_iauteur->text().isEmpty()) == false) //Si un auteur est spécifié
codeh += "Auteur : " + m_iauteur->text() + "\n";
codeh += "Date de création : " + (m_idate->date()).toString() + "\n";
if ((m_idescription->toPlainText().isEmpty()) == false) //Si une description est donnée
codeh += "Description :\n" + m_idescription->toPlainText() + "\n";
codeh += "*/\n\n";
}
//On génère ensuite la protection contre les inclusions multiples
if (m_inclusions->isChecked() == true) //Si la case est cochée, bien sûr
{
codeh += "#ifndef DEF_" + (m_inom->text().toUpper()) + "\n";
codeh += "#define DEF_" + (m_inom->text().toUpper()) + "\n\n";
}
//On génère la classe proprement dite
codeh += "class " + m_inom->text(); //class [Nom]
if ((m_imere->text().isEmpty()) == false) //Si une classe mère est spécifiée
codeh += " : public " + m_imere->text();
codeh += "\n{\n"; //Ici, on est après l'accolade d'ouverture de la classe
codeh += " public:\n";
if ((m_constructeur->isChecked() == true)) //Si on veut un constructeur
codeh += " " + m_inom->text() + "();\n";
if ((m_destructeur->isChecked() == true)) //Si on veut un destructeur
codeh += " ~" + m_inom->text() + "();\n";
codeh += "\n\n";
codeh += " protected:\n\n\n";
codeh += " private:\n\n\n";
codeh += "};";
if ((m_inclusions->isChecked() == true)) //Si on a une protection, on fait un endif
codeh += "\n\n#endif";
//Cpp
codecpp += "#include \"" + m_inom->text() + ".h\"\n\n\n";
if ((m_constructeur->isChecked() == true)){
codecpp += m_inom->text() + "::" + m_inom->text() + "()";
if ((m_imere->text().isEmpty()) == false)
codecpp += " : " + m_imere->text() + "()";
codecpp += "\n{\n\n}";}
codecpp += FInclude.getNom(1); //Mettre cette ligne en commentaire pour que le programme marche
static Dialogue resultat(codeh, codecpp);
resultat.modifier(codeh, codecpp);
resultat.show();
dejafait = true;
}//Fin de la génération
}
void Fenetre::menuIn()
{
FInclude.show();
}
/*
********************************
** Gère la liste d'inclusions **
********************************
*/
#ifndef DEF_INCLUSIONS
#define DEF_INCLUSIONS
#include <QtGui>
#include <vector>
#include "global.h"
class Inclusions : public QWidget
{
Q_OBJECT
public:
Inclusions();
bool getType(int numero);
QString getNom(int numero);
public slots:
void creernew();
//void supprimerdel();
private:
struct Inclus; //Structure pour les fichiers à inclure.
std::vector<Inclus*> tableInclus; //Tableau de pointeurs de fichiers à inclure. On utilisera new.
QPushButton *ok, *creer, *supprimer;
QGroupBox *tableau;
QGridLayout *LAYtableau; //Pour ranger les boutons des différents fichiers
QGroupBox *boutons;
QHBoxLayout *LAYboutons; //Pour ranger les boutons de la fenêtre
QVBoxLayout *LAYvertical; //Pour organiser les deux groupbox
QLabel *lselect, *lnom, *ltype; //1ere ligne du tableau, indique ce que représentent les widgets.
int derniereLigne; //Dernière ligne du tableau (0 par défaut)
};
#endif
inclusions.cpp
#include "inclusions.h"
#include "global.h"
struct Inclusions::Inclus
{
//Boutons : Chaque fichier a un coche de sélection, une barre de nom et un choix de type.
QCheckBox *iselect;
QLineEdit *inom;
QComboBox *itype; //Avec choix interne/externe. Par défaut externe.
//Variables
QString nom; //"" par défaut
bool selected; //False par défaut
bool interne; //False par défaut
//Si le fichier est interne, on rajoute .h et on entoure de " "
//Sinon, il est externe, et on entoure de < >
};
QString Inclusions::getNom(int numero)
{
return tableInclus[numero]->nom;
}
Inclusions::Inclusions() : QWidget()
{
derniereLigne = 0;
ok = new QPushButton("Terminer");
creer = new QPushButton("Ajouter");
supprimer = new QPushButton("Supprimer");
lselect = new QLabel("Choix");
lnom = new QLabel("Nom du fichier");
ltype = new QLabel("Type");
boutons = new QGroupBox;
LAYboutons = new QHBoxLayout;
LAYboutons->addWidget(ok);
LAYboutons->addWidget(creer);
LAYboutons->addWidget(supprimer);
boutons->setLayout(LAYboutons);
tableau = new QGroupBox;
LAYtableau = new QGridLayout;
LAYtableau->addWidget(lselect, 0, 0);
LAYtableau->addWidget(lnom, 0, 1);
LAYtableau->addWidget(ltype, 0, 2);
tableau->setLayout(LAYtableau);
LAYvertical = new QVBoxLayout;
LAYvertical->addWidget(tableau);
LAYvertical->addWidget(boutons);
this->setLayout(LAYvertical);
QObject::connect(ok, SIGNAL(clicked()), this, SLOT(close()));
QObject::connect(creer, SIGNAL(clicked()), this, SLOT(creernew()));
//QObject::connect(supprimer, SIGNAL(clicked()), this, SLOT(supprimerdel()));
}
void Inclusions::creernew()
{
Inclus* pointeur = NULL;
pointeur = new Inclus;
pointeur->iselect = new QCheckBox;
pointeur->inom = new QLineEdit;
pointeur->itype = new QComboBox;
pointeur->itype->setEditable(false);
pointeur->itype->addItem("Externe");
pointeur->itype->addItem("Interne");
pointeur->nom = "Ninouim";
pointeur->interne = false;
pointeur->selected = false;
LAYtableau->addWidget(pointeur->iselect, derniereLigne+1,0);
LAYtableau->addWidget(pointeur->inom, derniereLigne+1,1);
LAYtableau->addWidget(pointeur->itype, derniereLigne+1,2);
tableInclus.push_back(pointeur);
delete pointeur;
/*
tableInclus[derniereLigne]->nom = "";
tableInclus[derniereLigne]->interne = false;
tableInclus[derniereLigne]->selected = false;
tableInclus[derniereLigne]->iselect = new QCheckBox;
tableInclus[derniereLigne]->inom = new QLineEdit;
tableInclus[derniereLigne]->itype = new QComboBox;
tableInclus[derniereLigne]->itype->setEditable(false); //currentText() pour get.
tableInclus[derniereLigne]->itype->addItem("Externe");
tableInclus[derniereLigne]->itype->addItem("Interne");
LAYtableau->addWidget(tableInclus[derniereLigne]->iselect, derniereLigne+1, 0);
LAYtableau->addWidget(tableInclus[derniereLigne]->inom, derniereLigne+1, 1);
LAYtableau->addWidget(tableInclus[derniereLigne]->itype, derniereLigne+1, 2);
*/
derniereLigne ++;
}
Voilà, j'ai sûrement mal compris quelque chose, le problème est peut être évident, mais je ne le vois pas, merci d'avance
[Qt] Tableaux de pointeurs de structures...
× 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.