Problème avec Qt4

Problème avec Qt4 - C++ - Programmation

Marsh Posté le 17-02-2008 à 20:58:21    

Bonjour à vous tous,
 
J'ai un problème avec Qt4. Je dois créer l'interface graphique d'un logiciel d'acquisition et de visualisation de statistiques sportives.J'ai donc créé une fenêtre principale (la classe MainWindow) et une fenêtre de dialogue pour créer un joueur (la classe CreatePlayerDialog). J'ai créé la fenêtre de dialogue sous qt designer et j'ai codé dans le constructeur de createPlayerDialog les slots émit par le clique sur le bouton OK de cette fenêtre. Il y a deux slots pour ce bouton:
 -accept().
 -addElem(nom).
 
Mon problème réside dans le slot addElem(). C'est un slot qui s'applique sur le parent de la boite de dialogue donc sur ma fenêtre principale(j'espère que vous me suivez jusqu'à maintenant!) et le problème est donc que ce slot ne s'exécute pas.  
 
Je suis débutant en Qt et je n'est trouver que des tutoriaux en anglais donc je galère un peu à comprendre. Je ne vois pas d'où peux venir le problème.
voilà l'appel des slots pour le bouton OK de la fenêtre de dialogue de création du joueur :
 

Code :
  1. CreatePlayerDialog::CreatePlayerDialog(QWidget *parent) : QDialog(parent){
  2.         setupUi(this);
  3.         /*....*/
  4.         connect(okButton, SIGNAL(clicked()), parent, SLOT(addElem(nom)));//c'est ce signal qui ne marche pas
  5. connect(okButton, SIGNAL(clicked()), this, SLOT(accept()));
  6. }


 
Et voilà le code du slot addElem défini dans ma classe MainWindow :
 

Code :
  1. void MainWindow::addElem(QString *nom){
  2.     tree->addItem("nom" );
  3.     QMessageBox::warning(this,tr("salut" ),"passé",QMessageBox::Yes,QMessageBox::No,QMessageBox::Cancel);//j'ai mis ça pour faire un test mais      //cette boîte de dialog n'apparait jamais
  4. }


 
j'ai déclaré ce slot en "private slot :" mais j'ai aussi essayé de le déclarer en "public slot :" mais ça ne marche pas mieux.
 
J'espère que vous avez compris mon problème et que vous pourrez m'aider. Si une explication n'était pas assez claire n'hésitait pas a me contacter sur le forum j'ai la possibilité d'y aller pendant toute la semaine après je n'aurais plus le web.
 
Merci d'avance.
 

Reply

Marsh Posté le 17-02-2008 à 20:58:21   

Reply

Marsh Posté le 17-02-2008 à 21:18:09    

Salut,
 
Un slot ne peut être connecté qu'à un signal ayant la même signature, voire moins de paramètres. Mais jamais un slot ne peut avoir plus de paramètres que le signal; où irait-il en chercher la valeur sinon?
 
Pour résoudre ton problème, il faut 2 choses:

  • un signal newPlayerValidated(QString &name) (pour le nom, je te laisse adapter)
  • surcharger la méthode virtual void QDialog::accept() pour y émettre ce signal avec le nom récupéré dans le champ qui va bien, et appeller l'implémentation de QDialog

Reply

Marsh Posté le 17-02-2008 à 22:31:09    

Tout d'abord merci pour ta réponse aussi rapide,
ensuite j'aurais besoin de quelques éclaircissements sur tes propos:
 

Citation :


Pour résoudre ton problème, il faut 2 choses:

  • un signal newPlayerValidated(QString &name) (pour le nom, je te laisse adapter)
  • surcharger la méthode virtual void QDialog::accept() pour y émettre ce signal avec le nom récupéré dans le champ qui va bien, et appeller l'implémentation de QDialog


  • comment est-ce que je code le signal?? Je le déclare dans "signals : " et à l'intérieur du code de ce signal j'appelle le signal clicked()??
  • à quoi est-ce que ça me sert de surcharger la méthode accept() puisque s'il faut que le signal et le slot ai la même signature je peut bien laisser accept() avec le clicked(), non??


Encore merci pour ta réponse et j'espère ne pas faire trop le boulet !!!

Reply

Marsh Posté le 17-02-2008 à 22:45:20    

Oula, les signaux ont un corps, mais ce n'est pas toi qui l'écris :D
Va faire quelque tutos d'abord => http://doc.trolltech.com/4.3/tutorial.html
 
Pour le 2nd point, surcharger la méthode accept() te permet justement de rajouter ce que tu veux. Donc oui, tu le laisses associer au signal clicked() du bouton OK; lors de ce clic, il va se passer ça:
0. émission du signal clicked de QPushButton
1. Appel de CreatePlayerDialog::accept()
2. (ton code) émission du signal newPlayer("son nom" )
3. (ton code) appel de QDialog::accept()

Reply

Marsh Posté le 17-02-2008 à 23:29:42    

Si je résume ce que tu viens de me dire :
 -quand l'utilisateur va cliquer sur le bouton ça va appeler un slot accept() que j'aurais redéfinis dans la classe CreatePlayerDialog.
 -ensuite je vais créer mon joueur avec "son nom" dans une fonction. Cette fonction va émettre le signal qui va appeler le slot accept() de la classe QDialog.
 
Mais comment je fais pour surcharger le slot accept() puisque je sait juste que la méthode accept() renvoi un entier (et encore je suis plus trop sur maintenant que j'y écrit!!)??
Et ensuite je ne comprend pas bien comment ceci va me permettre de récupérer le nom dans ma fenêtre principale.
 
Je suis désolés mais je ne comprend pas très bien les tuto que tu m'a filé puisqu'ils sont en anglais et que l'anglais et moi sa fait 3 !!!!
 
Encore merci pour tes réponses je pense que pour ce soir je vais arrêter le  Qt je m'y remettrais demain parce que la ça me prend un peu la tête!!!
 
Bonne nuit à tout le monde!!

Reply

Marsh Posté le 18-02-2008 à 01:22:02    

Je peux pas faire grand chose de plus pour t'aider. Bosse les tutos; de toute façon sans anglais tu feras pas grand chose en prog.
 
Parce que là tu n'as visiblement rien compris à la façon dont Qt fonctionne, et c'est pas avec un post de forum que je vais t'aider (te filer le code ne compte pas comme une façon d'aider si tu ne le comprends pas).

Reply

Marsh Posté le 18-02-2008 à 11:42:39    

Oui tu as raison et je ne recherche pas le code tout fait je pense que je vais me débrouiller tu m'a bien avancé.
Je te remercie.
Bonne journée.

Reply

Marsh Posté le 18-02-2008 à 20:50:21    

Bonsoir à vous tous,
J'aurai encore besoin de votre aide.
J'ai réussi à réparer le problème de signal/slots que je vous ai exposé précédemment mais maintenant il passe deux fois dans le slot pour un seul signal. Je ne vois pas quel est le problème mais je pense que c'est un petit truc que j'aurais pas vu.  
Tenez moi au courant si vous avez besoin du code.
 
Merci d'avance

Reply

Marsh Posté le 19-02-2008 à 01:24:55    

Tu as avoir fait 2 connections à ce signal. Une connexion = un appel.

Reply

Marsh Posté le 19-02-2008 à 10:58:53    

IrmatDen a écrit :

Tu as avoir fait 2 connections à ce signal. Une connexion = un appel.


 
Voici mon slot :
 

Code :
  1. void MainWindow::addElem(QString nom, QString licence){
  2.     Joueur *J1 = new Joueur(nom,licence);
  3.     players.push_back(J1);
  4.     QTreeWidgetItem *root;
  5.     root = new QTreeWidgetItem(arbre);
  6.     root->setText(0, J1->getNom());
  7.     if (!arbre->currentItem())
  8.         arbre->setCurrentItem(root);
  9. }


 
Et voici mon seul appel :
 

Code :
  1. CreateTeamDialog::CreateTeamDialog(QWidget *parent) : QDialog(parent){
  2.     setupUi(this);
  3.     QRegExp chaineRegExp("[A-Za-z]{3,30}" );
  4.     nomLineEdit->setValidator(new QRegExpValidator(chaineRegExp,this));
  5.     connect(okButton, SIGNAL(clicked()), this, SLOT(on_okButton_clicked()));
  6.     connect(this, SIGNAL(go_add_elem(QString)), parent, SLOT(addElemTeam(QString)));
  7.     connect(cancelButton, SIGNAL(clicked()), this, SLOT(reject()));
  8. }


 
J'ai pas l'impression d'avoir fait deux appel. C'est pour ça que je ne comprend pas.
Merci pour ta réponse et désolé de pas avoir répondu plus tôt.


Message édité par fardke1 le 19-02-2008 à 10:59:59
Reply

Marsh Posté le 19-02-2008 à 10:58:53   

Reply

Marsh Posté le 19-02-2008 à 12:47:58    

Le connect "doit" se faire dans la classe mère; en effet CreateTeamDialog n'aura pas forcément toujours le parent disposant de ce slot. Si c'est mainwindow qui s'occupe de la connection, tu rends ta boîte de dialogue plus indépendante de mainwindow.
 
Quel est le constructeur de MainWindow? C'est quoi le code de on_okButton_clicked?

Reply

Marsh Posté le 19-02-2008 à 13:14:34    

Désolés là j'ai pas le temps de te mettre mon code j'ai un rendez vous mais je rentre dans une heure je te mettrais tous les codes nécessaires

Reply

Marsh Posté le 19-02-2008 à 16:05:25    

IrmatDen a écrit :

Quel est le constructeur de MainWindow? C'est quoi le code de on_okButton_clicked?


 
Constructeur de MainWindow :

Code :
  1. MainWindow::MainWindow(){
  2.     arbre = new QTreeWidget;
  3.     connect(arbre,SIGNAL(itemActivated(QTreeWidgetItem*,int)),this, SLOT(setCurrent(QTreeWidgetItem*)));
  4.     label = new QLabel("" );
  5.     QStringList enTete;
  6.     enTete << tr("Equipe" );
  7.     arbre->setHeaderLabels(enTete);
  8.     QSplitter *spliter = new QSplitter(Qt::Horizontal);
  9.     spliter->addWidget(arbre);
  10.     spliter->addWidget(label);
  11.     spliter->setStretchFactor(1,1);
  12.     setCentralWidget(spliter);
  13. createActions();
  14. createMenus();
  15. //createContextMenu();
  16. createToolBars();
  17. createStatusBar();
  18. //readSettings();
  19. setWindowIcon(QIcon(":/images/icon.png" ));
  20. }


code de on_okButton_clicked :

Code :
  1. void CreatePlayerDialog::on_okButton_clicked(){
  2.     emit go_add_elem(nomLineEdit->text(),licenceLineEdit->text(), equipe);
  3.     //accept();
  4. }


 
petite modification car tout à l'heure j'ai mis le constructeur de  CreateTeamDialog alors que ce n'est pas la fenêtre concerné mais plutôt CreatePlayerDialog :
 

Code :
  1. CreatePlayerDialog::CreatePlayerDialog(QTreeWidgetItem *root, QWidget *parent) : QDialog(parent){
  2.     setupUi(this);
  3.     equipe = new QTreeWidgetItem(root);
  4.     QRegExp chaineRegExp("[A-Za-z]{3,30}" );
  5. QRegExp licenceRegExp("[0-9]{5}" );
  6. QRegExp maillotRegExp("[1-9]{1}" );
  7.     nomLineEdit->setValidator(new QRegExpValidator(chaineRegExp,this));
  8.     prenomLineEdit->setValidator(new QRegExpValidator(chaineRegExp,this));
  9.     licenceLineEdit->setValidator(new QRegExpValidator(licenceRegExp,this));
  10.     maillotLineEdit->setValidator(new QRegExpValidator(maillotRegExp,this));
  11.  connect(okButton, SIGNAL(clicked()), this, SLOT(on_okButton_clicked()));
  12.     connect(this, SIGNAL(go_add_elem(QString, QString, QTreeWidgetItem *)), parent, SLOT(addElem(QString, QString, QTreeWidgetItem *)));
  13. connect(cancelButton, SIGNAL(clicked()), this, SLOT(reject()));
  14. }


 
Excuse moi pour le temps de réponse et pour l'erreur du post précédent.

Reply

Marsh Posté le 19-02-2008 à 16:07:04    

Je vais essayer de mettre la connect dans le MainWindow comme tu me l'as dit je te dirais si ça a fonctionné.

Reply

Marsh Posté le 19-02-2008 à 16:07:26    

Bizarre, y'a rien qui génère un double appel du slot là :/ (Par contre y'a toujours l'erreur de connecter le signal au mauvais endroit)
 
Tu le vois à quoi que le slot est appelé en double?

Reply

Marsh Posté le 19-02-2008 à 16:12:05    

Je vois que le slot est appelé en double car j'affiche le nom du joueur créé dans un QTreeWidget et qu'il en affiche 2 quand j'en créé 1.
Et j'ai testé en rajoutant un QMessageBox dans le slot on_okBouton_clicked et en fait celui la est déjà appelé 2 fois....
Est-ce que ce serait possible que le problème vienne du fait que j'ai créé la fenetre creatPlayerDialog sous QTDesigner???

Reply

Marsh Posté le 19-02-2008 à 16:14:01    

Autre chose je vois pas comment je peux appeler le signal dans MainWindow vu que le signal est fait lorsque l'on appui sur le bouton ok de ma fenêtre createPlayerDialog

Reply

Marsh Posté le 19-02-2008 à 16:15:13    

Au fait je tiens à le re-préciser je ne veux pas le code tout fait je tiens absolument à comprendre. Je trouve cette bibliothèque très intéressante donc je veux comprendre!!!!

Reply

Marsh Posté le 19-02-2008 à 16:21:55    

fardke1 a écrit :

Est-ce que ce serait possible que le problème vienne du fait que j'ai créé la fenetre creatPlayerDialog sous QTDesigner???


Bon hint :jap:  
T'aurais pas fait une connection du signal clicked() vers le bouton ok accept() dans le designer par hasard? Si c'est le cas, setupUi() s'en occupe déjà, d'où le double appel.

fardke1 a écrit :

Autre chose je vois pas comment je peux appeler le signal dans MainWindow vu que le signal est fait lorsque l'on appui sur le bouton ok de ma fenêtre createPlayerDialog


Tu n'appelles pas le signal, tu y connectes un slot.

fardke1 a écrit :

Au fait je tiens à le re-préciser je ne veux pas le code tout fait je tiens absolument à comprendre. Je trouve cette bibliothèque très intéressante donc je veux comprendre!!!!


T'inquiétes, t'auras pas ça de moi en général :D

Reply

Marsh Posté le 19-02-2008 à 16:31:19    

C'est bon sa venait du fait que je l'avais fait sous QtDesigner.
Je viens de le faire à la main et c'est bon sa ne le fait qu'une seule fois.
Mais je vois pas bien pourquoi je ne peux pas le faire avec QtDesigner puisque je n'ai pas connecter mes bouton à accept ou tout autre slot dans QtDesigner....

Reply

Marsh Posté le 19-02-2008 à 20:35:48    

Tu peux aussi le faire sous le designer mais il ne faut à ce moment pas le rajouter dans ton propre code. Le simple fait que ton slot était appelé 2 fois prouve bien que la connection dans le designer est fonctionnelle ;)

Reply

Marsh Posté le 20-02-2008 à 19:40:17    

Bonjour à vous tous,
Est ce que quelqu'un saurait quelle est la fonction pour supprimer un QTreeWidgetItem sous QT 4.1 parce que j'ai vu removeItemWidgetmais à priori elle n'est compatible qu'avec QT4.2 (ou QT4.3 je me souviens plus)
 
Merci d'avance

Reply

Marsh Posté le 20-02-2008 à 19:53:11    

Heu, je sais pas où tu as vu cette fonction :D
Si mes souvenirs sont bons, un simple delete sur un QTreeWidgetItem* notifie la vue de sa suppression et zou, il est plus là. Si tu veux le déplacer par contre, il faut te servir des méthode QTreeWidget::takeTopLevelItem* pour les item racines, et QTreeWidgetItem::take* pour les items fils d'autres items.

 

Edit: par contre tu devrias créer un nouveau fil pour de nouvelles questions, c'est plus facile à chercher par la suite.


Message édité par IrmatDen le 20-02-2008 à 19:53:39
Reply

Marsh Posté le 20-02-2008 à 21:11:24    

ok je te remercie encore une fois

Reply

Marsh Posté le    

Reply

Sujets relatifs:

Leave a Replay

Make sure you enter the(*)required information where indicate.HTML code is not allowed