[Qt designer débutant] Problème de connexions des slots

Problème de connexions des slots [Qt designer débutant] - C++ - Programmation

Marsh Posté le 24-08-2013 à 16:16:19    

Bonjour à tous,
 
 
Débutant avec Qt designer, je me prend la tête depuis une semaine avec les tuto du site du zéro et les forums, pour arriver à coder une interface simple.
 
Je m'explique, j'ai utilisé Qt designer pour mettre au point mon interface finale, et me retrouve donc avec 4 fichiers :
 
main.cpp
mainwindows.h
mainwindows.cpp
mainwindows.ui
 
Lorsque je tente de connecter mes pushbutton à un WidgetTable, via le menu graphique d'édition de FP.ui je ne trouve pas le slot (insertRow()) que je cherche, alors que quand j'y connecte une SpinBox, le slot insertRow() y est et fonctionne parfaitement ...
 
Image de la liaison de mon button "add step" vers la table :
 
http://nsa33.casimages.com/img/2013/08/24/130824041120954924.jpg
 
La commande insertRow() est présente mais grisée, et quand je selectione un signal, elle disparait :
 
http://nsa33.casimages.com/img/2013/08/24/130824041003397572.jpg
 
Du cout je suis allé chercher dans le .ui, mais impossible de modifier le code de ce fichier :
 
http://nsa33.casimages.com/img/2013/08/24/130824041505899587.jpg
 
Comment puis-je faire svp? J'ai lu qu'il était souvent obligatoire de creer ses propres slots et connexions manuellement, suis-je obligé de passer par cette étape svp?  
 
Merci d'avance pour votre réponse

Reply

Marsh Posté le 24-08-2013 à 16:16:19   

Reply

Marsh Posté le 24-08-2013 à 20:41:06    

Bonjour !
 
Vous voulez connecter le signal "clicked" du bouton, qui ne passe pas de paramètre, au slot "insertRow(int)", qui prend un entier en paramètre.
 
C'est bien évidemment impossible, car quelle serait alors la valeur du paramètre du slot ?
 
La seule possibilité est de passer par un slot à vous, qui ne prend pas de paramètre, que vous connectez manuellement au signal "clicked()" du bouton, puis, dans le code de ce slot, vous appelez le slot "insertRow" en lui passant le paramètre que vous voulez.
 
Bonne continuation !

Reply

Marsh Posté le 24-08-2013 à 21:30:16    

Merci à vous pour cette réponse,
 
du coup je me suis mis à chercher comment créer des slots perso, et je me retrouve avec un léger pb d'architecture, en effet je ne sais pas où mettre la commande QObject::connect() ...
 
Voici ma class table dans laquelle j'ai crée mon slot "addRow" :
 
le fichier : table.h
 

Code :
  1. #ifndef table_H
  2. #define table_H
  3. #include <QTableWidget>
  4. class table
  5. {
  6. public: table();
  7. public slots:
  8.      void addRow();
  9. private:
  10.      QPushButton *boutonAddStep;
  11.      QTableWidget *tableWidget;
  12. };
  13. #endif


 
Mon fichier table.cpp

Code :
  1. #include "table.h"
  2. #include <QTableWidget>
  3. using namespace std;
  4. table::table()
  5. {
  6.     QTableWidget tableau(10, 2);
  7.     tableau.setGeometry(10, 90, 281, 281);
  8. }
  9. void table::addRow()
  10. {
  11. int row=tableWidget->rowCount();
  12. tableWidget->insertRow(row);
  13. }


 
et mon main.cpp

Code :
  1. #include "table.h"
  2. int main(int argc, char *argv[])
  3. {
  4.     QApplication app(argc, argv);
  5.     // Initialisation de la fenetre initiale
  6.     QMainWindow MainWindow;
  7.    //Initialisation du bouton "AddStep"
  8.    QPushButton boutonAddStep("Add Step", &MainWindow);
  9.        boutonAddStep.setCursor(Qt::PointingHandCursor);
  10.        boutonAddStep.setGeometry(300, 130, 71, 23);


 
La méthode que j'ai suivi propose d'initialiser le bouton et le tableau dans le constructeur "table" du fichier table.cpp, par contre si je fais ça il ne m'affiche plus le tableau, il faut que jappele le tableau dans le main mais ne sais pas comment faire.
 
Ensuite ils expliquent qu'il faut placer la commande

Code :
  1. QObject::connect(boutonAddStep,SIGNAL(clicked()),this,SLOT(addRow()));

après l'initialisation du tableau dans le constructeur, mais quand j'effectue ceci la compilation ne se fait pas et m'affiche un message d'erreur.
 
Bref, j'ai beau avoir lu les tuto sur le site du zéro, ca passe avec des exemples concrêt, mais dès que je change de class à utiliser, je me perds assez rapidement ...
 
Si une ame charitable pouvais expliquer à un débutant comment creer des slots personnalisés, et comment les ratacher à un QWidgetTable svp :)
 
Merci d'avance!

Reply

Marsh Posté le 25-08-2013 à 05:03:15    

Bonjour !
 
Il vous manque simplement la macro Q_OBJECT dans la définition de la classe Table, pour que le slot que vous déclarez soit pris en compte par le moc (meta-object compiler).  
 
Une fois cette macro ajoutée, vous devrez re-générer le makefile à l'aide de la commande qmake, sinon vous aurez un problème lors de l'édition de liens.
 
Bonne continuation !

Reply

Marsh Posté le 25-08-2013 à 12:50:24    

Merci pour votre réponse,
 
J'ai donc suivis vos conseil, voici mes nouveaux codes :
 
table.h
 

Code :
  1. #ifndef table_H
  2. #define table_H
  3. #include <QTableWidget>
  4. #include <QPushButton>
  5. class table
  6. {
  7.     Q_OBJECT;
  8. public: table();
  9. public slots:
  10. void addRow();
  11. private:
  12.      QTableWidget *tableWidget;
  13.      QPushButton *boutonAddStep;
  14. };
  15. #endif


 
table.cpp

Code :
  1. #include "table.h"
  2. #include <QTableWidget>
  3. using namespace std;
  4. table::table()
  5. {
  6.     QTableWidget tableau(10, 2);
  7.     tableau.setGeometry(10, 90, 281, 281);
  8.     QObject::connect(boutonAddStep,SIGNAL(clicked()),this,SLOT(addRow()));
  9. }
  10. void table::addRow()
  11. {
  12. int row=tableWidget->rowCount();
  13. tableWidget->insertRow(row);
  14. }


 
main.cpp
 

Code :
  1. #include "table.h"
  2.     int main(int argc, char *argv[])
  3.     {
  4.         QApplication app(argc, argv);
  5.         // Initialisation de la fenetre initiale
  6.         QMainWindow MainWindow;
  7.      
  8.         // Affichage et modification du tableau initialisé dans table.cpp


 
Concernant le qmake, j'ai effectué comme ceci :
 
http://nsa34.casimages.com/img/2013/08/25/130825124538549430.jpg
 
J'ai ensuite tenté de compiler et il m'affiche :
 

Citation :

erreur : no matching function for call to 'QObject::connect(QPushButton*&, const char*, table* const, const char*)'


 
 
Et du coup ce que je ne comprends pas bien c'est qu'il faut déclarer les objets qui serviront au connect, comme attributs de la classe table? ( ici "tableWidget" et "boutonaddstep" )
 
du cout dans le constructeur, quand je crée le "tableau", c'est lui que je cherche à connecter au bouton "butonaddstep" ( qui n'est pas encore crée lui ... je le crée dans le main.cpp c'est ça? ), et il faut ensuite que j'affiche dans mon main.cpp ce fameux tableau qui est connecté au bouton "boutonaddstep", il faut donc que j'utilise le constructeur dans le main, à savoir qqchose comme

Code :
  1. table::table(){}

et là il m'affichera "tableau" avec la géométrie définie dans le table.cpp, et la connexion faite au bouton "boutonaddstep" ( qui lui sera encore à créer dans le main.cpp pour que tout soit bon), c'est bien ça?
 
 
Merci d'avance pour vos réponse, je me perds dans le système des classes et des connexions ...
 

Reply

Marsh Posté le 26-08-2013 à 10:27:54    

Bonjour !
 
La réponse était tellement évidente que je ne l'avais pas vue ... Pour pouvoir utiliser les slots/signaux, la classe table doit dériver de QObject.
 
C'est d'ailleurs étonnant qu'il n'y ait pas une erreur de remontée lors du qmake, dans mon souvenir c'était le cas ...
 
Il n'est pas nécessaire d'avoir tout dans la même classe, il suffit d'avoir accès aux deux objets à "connecter" au moment de faire le "connect".
 
Sinon, pour votre "boutonaddstep" vous devez le créer AVANT de faire le connect.
 
Bonne continuation !

Reply

Marsh Posté le 26-08-2013 à 14:55:03    

Merci pour vos précisions Farian, néanmoins un pb persiste ... :(
 
j'ai bien fait hérité la class table de Q_OBJECT :
 
table.h

Code :
  1. #ifndef table_H
  2. #define table_H
  3. #include <QTableWidget>
  4. #include <QPushButton>
  5. #include <QObject>
  6. class table : public Q_OBJECT
  7. {
  8. table();
  9. public slots:
  10. void addRow();
  11. private:
  12.      QTableWidget *tableWidget;
  13.      QPushButton *boutonAddStep;
  14. };
  15. #endif


 
et j'ai 15 erreurs de compilation (j'ai refais qmake sur le projet) dont:  
 

Citation :

erreur : forward declaration of 'class table'
erreur : invalid use of incomplete type 'class table'


 
Une idée svp? :)

Reply

Marsh Posté le 26-08-2013 à 15:06:29    

Bonjour !  
 
La classe doit dériver de QObject, et inclure la macro Q_OBJECT

Code :
  1. ...
  2. class  table : public QObject
  3. {
  4. Q_OBJECT
  5. public:
  6.     table();
  7. ...
  8. };


 
Bonne continuation

Reply

Marsh Posté le 26-08-2013 à 19:00:56    

La compilation se fait! Merci encore pour votre aide! :)
 
du cout petite précision par rapport aux objets sélectionnés,
 

Code :
  1. class table : public QObject
  2. {
  3. Q_OBJECT
  4. public :
  5.     table();
  6. public slots:
  7.     void addRow();
  8. private:
  9.      QTableWidget *tableWidget;
  10.      QPushButton *boutonAddStep;
  11. };
  12. #endif


ici on définie la classe table, qui possède comme méthode ( en slot ) le addRow, et comme attribut les objets tableWidget et boutonAddstep.
 
ensuite l'on définie dans le table.cpp

Code :
  1. #include "table.h"
  2. #include <QTableWidget>
  3. using namespace std;
  4. table::table()
  5. {
  6. QTableWidget tableau(2, 2);
  7. tableau.setGeometry(10, 90, 281, 281);
  8. QObject::connect(boutonAddStep,SIGNAL(clicked()),this,SLOT(addRow()));
  9. }
  10. void table::addRow()
  11. {
  12. int row=tableWidget->rowCount();
  13. tableWidget->insertRow(row);
  14. }


 
-qu'il faut créer un nouvel objet nomé tableau, qui sera lié au bouton addStep via le connect, et que cette liaison aura pour effet addRow sur l'objet nommé "tableau"
-que addRow() ajoute une ligne au nombre de ligne déjà présente dans tableWidget.
 
et ensuite dans mon main, comment je fais pour appeler et afficher les objets tableau et boutonaddstep svp?
 
Merci d'avance!
 
 
 
 

Reply

Marsh Posté le 14-09-2013 à 11:50:20    

petit up pour finaliser ma compréhension de la définition de nouveaux slots svp :)

Reply

Sujets relatifs:

Leave a Replay

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