Forum |  HardWare.fr | News | Articles | PC | S'identifier | S'inscrire | Shop Recherche
3286 connectés 

 


 Mot :   Pseudo :  
 
 Page :   1  2
Page Suivante
Auteur Sujet :

c++ et Qt

n°1228058
HelloWorld
Salut tout le monde!
Posté le 21-10-2005 à 14:35:53  profilanswer
 

Reprise du message précédent :
Si le connect échoue un message devrait être affiché par Qt dans la console. A priori, je dirais que tu as oublié de moc'er ta classe Case.


---------------
FAQ fclc++ - FAQ C++ - C++ FAQ Lite
mood
Publicité
Posté le 21-10-2005 à 14:35:53  profilanswer
 

n°1228322
i'n'i
Posté le 21-10-2005 à 17:56:33  profilanswer
 

En effet je ne fait pas de moc! ça sert à quoi déjà?
Moi je fais
- qmake- project
- qmake
- make
 
Quand dois-je faire le moc, et que dois taper?  
 
Merci beaucoup.

n°1228407
IrmatDen
Posté le 21-10-2005 à 20:03:54  profilanswer
 

Le moc se fait automatiquement si tu inclues la macro Q_OBJECT au début de ta classe. J'ai vérifié rapidement les posts précédent sans le voir.
Ca doit donner:

Code :
  1. class MyWidget : public QWidget
  2. {
  3.     Q_OBJECT
  4.     public:
  5.         ...
  6. };


 
Cette macro permet à qmake de détecter toutes les classes utilisant le mécanisme de signaux/slots et smart pointers.
Une fois qu'il l'a détecté, le passage au moc se fait tout seul. Concrétement moc te créer un fichier implémentant les dits concepts.

n°1228480
i'n'i
Posté le 21-10-2005 à 21:45:00  profilanswer
 

Encore merci, je vais essayer ça!
 
TYant que j'y suis, est-ce que tu peux m'aider sur ce petit problème :  
 
j'ai une classe qui fait un "plateau" de 4*4 myWidget :
 
     QGridLayout *grid = new QGridLayout();
      for (int row = 0; row < 4; ++row)  
      {
             for (int column = 0; column < 4; ++column)  
             {
                 grid->addWidget(new myWidget, row, column);
             }
         }
     setLayout (grid);
 
Mais voilà :
- Comment acceder ensuite à une myWidget ? (par exemple celle qui est à la ligne 2, colonne 3).
- Si je fais un grid->addWidget(new myWidget, 2, 3); alors qu'il existe déjà une myWidget à cet emplacement, que devient l'ancienne? (dois-je faire un removeWidget avant?)
 
Merci.

n°1228793
IrmatDen
Posté le 22-10-2005 à 19:13:14  profilanswer
 

Honnétement, je n'ai jamais fait ce genre de manipulation :(
 
Tu peux peut-être voir du côté de QLayout::iterator() (http://doc.trolltech.com/3.3/qlayout.html#iterator), voir si c'est réimplémenté dans le QGridLayout.
 
Je ne peux que te conseiller de faire des essais, désolé. Par contre, tiens nous au courant de ce que tu trouves :)

n°1229345
HelloWorld
Salut tout le monde!
Posté le 24-10-2005 à 09:30:35  profilanswer
 

Garde un trace des widgets que tu alloues. Le QGridLayout n'est là que pour les placer.
Le moc, c'est ce qui s'occupe de faire fonctionner le mécanisme signal / slot...


---------------
FAQ fclc++ - FAQ C++ - C++ FAQ Lite
n°1231436
i'n'i
Posté le 26-10-2005 à 12:38:50  profilanswer
 

En fait je vais m'en sortir avrec ma grid, en gardant des traces de mes Widget.
 
J'ai un autre souci :  
j'ai ceci :  
 
J'ai trois classe 1, 2, 3 correspondant à 2 widget (1, 2) et un pushbouoton (3). La 1 crée la 2 qui crée la 3, j'ai donc la 3 dans la 2 qui elle est dans la 1.
 
Je veut que lorsque qu'on click sur la 3, la 1 se quitte.
 
Je fais donc dans ma classe 2:
...
grid->addWidget(3, row, column);
connect(3, SIGNAL(clicked()), this->parent, SLOT(quit()));
...
 
et ça ne marche pas.
 
En fait, quand je fais mon connect, le slot que je passe dois etre defini dans quelle widget?
 
NB : - je ne veut pas utiliser de qApp->quit())
       - this->parent représente ici ma widget 1.
       - je fais des Q_OBJECT dans les 3 classes (donc des moc)
 
Merci de m'aider car je suis coincé!

n°1231554
HelloWorld
Salut tout le monde!
Posté le 26-10-2005 à 14:47:08  profilanswer
 

prends le temps de comprendre les signaux-slots. Une fois que t'as bien pigé ça, tu as à peu près pigé Qt.

Code :
  1. connect(3, SIGNAL(clicked()), this->parent, SLOT(quit()));


là tu connectes le signal "clicked" du widget 3 au slot "quit" de ton parent. Il faut donc que ton parent ait un slot "quit", et s'il existe, c'est ce qui sera appelé. Toi tu veux que le soit le slot "close" de 1 qui soit appelé. Je te laisse deviner ce qu'il faut changer...
 
PS: Q_OBJECT est nécessaire si tu definis des signaux ou des slots. Là, tu vas utiliser un slot hérité de QWidget ("close" ), donc à priori tu n'as pas besoin de mettre Q_OBJECT car tu n'a à priori pas besoin de définir de slot ou de signal.


Message édité par HelloWorld le 26-10-2005 à 14:48:33

---------------
FAQ fclc++ - FAQ C++ - C++ FAQ Lite
n°1232844
i'n'i
Posté le 27-10-2005 à 18:38:46  profilanswer
 

Merci à toi Helloworld, j'ai rectifier mon connect.  
 
J'ai une autre question (pas compliquée je pense).
J'ai toujours trois classe UN, DEUX, TROIS correspondant à 2 widget (UN, DEUX) et un pushbouoton (TROIS). La UN crée la DEUX qui crée la TROIS, j'ai donc la TROIS dans la DEUX qui elle est dans la UN.  
 
Je voudrai qu'elles puissent communiquer : de la DEUX, agir sur la UN, etc...
Donc quand je suis dans ma widget 1 et que je créer la DEUX, je passe l'adresse de la UN (this en parametre) soit :
 
dans ma classe UN :  
addWidget(new DEUX(this));
 
mais voilà, quel est le prototype de mon contructeur de la classe DEUX?
-     DEUX::DEUX(QWidget *parent)
        : QWidget(parent)  
 
mais du coup parent n'est pas de type UN.
 
- DEUX::DEUX(UN *parent)
        : DEUX(parent)
et creer un constructeur de recopie?
mais ça, le compilateur rejete car "UN n'est pas une classe direct de DEUX".
 
Comment dois-je faire pour creer des classes (dervivées de Widget) imbriquées et qu'elles puissent communiquer?
 
Merci.

n°1232845
i'n'i
Posté le 27-10-2005 à 18:39:58  profilanswer
 

SANS LES SMILEYS et avec une petite modif :
 
Merci à toi Helloworld, j'ai rectifier mon connect.  
 
J'ai une autre question (pas compliquée je pense).  
J'ai toujours trois classe UN, DEUX, TROIS correspondant à 2 widget (UN, DEUX) et un pushbouoton (TROIS). La UN crée la DEUX qui crée la TROIS, j'ai donc la TROIS dans la DEUX qui elle est dans la UN.  
 
Je voudrai qu'elles puissent communiquer : de la DEUX, agir sur la UN, etc...  
Donc quand je suis dans ma widget 1 et que je créer la DEUX, je passe l'adresse de la UN (this en parametre) soit :  
 
dans ma classe UN :  
addWidget(new DEUX(this));  
 
mais voilà, quel est le prototype de mon contructeur de la classe DEUX?  
-     DEUX:: DEUX(QWidget *parent)  
        : QWidget(parent)  
 
mais du coup parent n'est pas de type UN.  
 
- DEUX:: DEUX(UN *parent)  
        : UN(parent)  
et creer un constructeur de recopie?  
mais ça, le compilateur rejete car "UN n'est pas une classe direct de DEUX".  
 
Comment dois-je faire pour creer des classes (dervivées de Widget) imbriquées et qu'elles puissent communiquer?  
 
Merci.

mood
Publicité
Posté le 27-10-2005 à 18:39:58  profilanswer
 

n°1233211
HelloWorld
Salut tout le monde!
Posté le 28-10-2005 à 10:18:04  profilanswer
 

Mauvais design.
A mon avis, un widget enfant ne devrait jamais agir sur son parent. Ca augmente le couplage (ton enfant est dépendant du parent donc difficilement réutilisable), ça casse l'encapsulation (l'enfant doit pouvoir modifier l'état interne du parent...), sans parler de faire du downcasting dans ton cas (avec qobject_cast, mais c'est la plupart du temps une mauvaise pratique), etc...
Toujours à mon avis, un enfant ne devrait que renvoyer des notification à son parent, et c'est ce dernier qui s'auto-modifie. Ainsi, au lieu que DEUX modifie UN quand TROIS est cliqué, DEUX informe UN que TROIS a été cliqué (ou que l'action représentée par TROIS est demandée), et UN se modifie.
En QT, les signaux/slot te permettent facilement de faire ça. DEUX émet un signal, et UN s'y connecte après l'avoir créé. Ainsi, le code que tu voulais initialement mettre dans DEUX est déplacé dans le slot de UN connecté au signal de DEUX.


---------------
FAQ fclc++ - FAQ C++ - C++ FAQ Lite
n°1233323
i'n'i
Posté le 28-10-2005 à 11:35:56  profilanswer
 

Ta solution me convient parfaitement.
 
Donc dans ma classe DEUX :  
--------------------------
public slots :
    slot2(){
emit signal_2();
    }
...
connect(TROIS, SIGNAL(clicked()), this, SLOT(slot2()));
--------------------------
dans ma classe UN :
...
public slots :
    slot1(){
    }
 
signals:
   void signal_2();
...
connect(UN, SIGNAL(signal_2()), this, SLOT(slot1()));
----------------------------
 
Est-ce que c'est bon? Faut-il definir signal_2(), si oui, quoi mettre à l'intérieur.
Est-ce que DEUX connaitra signal_2 (définie dans UN)?
 
Merci.

n°1233342
i'n'i
Posté le 28-10-2005 à 11:58:24  profilanswer
 

ça marche!!!!!!!!!!!!
 
 
J'ai fait dans ma classe DEUX :  
--------------------------  
signals:  
   void signal_2();  
 
public slots :  
    slot2(){  
emit signal_2();  
    }  
...  
connect(TROIS, SIGNAL(clicked()), this, SLOT(slot2()));  
--------------------------  
dans ma classe UN :  
...  
public slots :  
    slot1(){  
    }  
...  
connect(DEUX, SIGNAL(signal_2()), this, SLOT(slot1()));  
----------------------------  
 
Merci bien HelloWorld ;)

n°1233632
i'n'i
Posté le 28-10-2005 à 15:55:11  profilanswer
 

J'ai vu qu'avec un slot, on pouvait passer des paramètres. Est-ce qu'il y a des restrictions sur ces paramètres? (nombre, type de base, classe) Car dès que je redefinie mon slot avec un parametre ça ne marche plus.
 
??
Merci.

n°1234092
IrmatDen
Posté le 29-10-2005 à 14:34:17  profilanswer
 

Salut,
 
La seule restriction sur ces paramètres est qu'ils doivent correspondre entre le signal émis et le slot jusqu'à un certain point. Tu peux avoir des signaux paramétré et les brancher sur des slots qui n'acceptent pas de paramètres, ou moins de paramètres mais chaque paramètre doit correspondre en type et en ordre.
 
Exemple de correspondance:

Code :
  1. connect(obj1, SIGNAL(mySig(int)), obj2, SLOT(mySlot(int)));


Ici, les paramètres sont les mêmes, donc aucun souci.
 
Tu as d'autres d'utilisation ici:
http://prog.qt.free.fr/viewtopic.php?p=5883#5883

n°1235698
i'n'i
Posté le 01-11-2005 à 15:08:41  profilanswer
 

Merci, mais moi je voudrais faire ceci :
 
class DEUX
{
....
  public slots:
    void slot2(int);
....
void mafct
  {
    int k=5;
    connect(TROIS, SIGNAL(clicked()), this, SLOT(slot2(k)));
    ...
  }
...
}  
 
Je veux passer à mon slot un argument qui est une variable local à mafct, et ça, à ce que j'ai lu et compris on dirait que je ne peux pas.
Mon signal clicked() ne peux pas avoir d'argument!!
Vous-voyez mon problème? J'espère que je me suis bien exprimé ;)  
 
D'avance merci.

n°1236363
IrmatDen
Posté le 02-11-2005 à 14:04:54  profilanswer
 

Yep, tu t'es bien exprimé :)
Mais, non, ce n'est pas possible. Par contre, à en voir ton code, tu peux en faire une variable de DEUX.
 
Sinon, tu n'en as pas assez dit pour envisager une autre solution. Tu peux aller lire ça et voir si l'une d'elles correspond à ce que tu veux: http://doc.trolltech.com/qq/qq10-signalmapper.html

n°1236431
i'n'i
Posté le 02-11-2005 à 14:36:36  profilanswer
 

Merci, en fait, vu que ce n'est pas possible avec les signals/slots, le meilleur moyen de passer des variables entre des classes (dérivées de widgets) "imbriquées" (widget3 dans widget2, dans widget1) est d'utiliser le "parent" de : MyWidget(QWidget *parent = 0);
 
Non? (il y en a un autre?).
 
Merci

n°1237472
i'n'i
Posté le 03-11-2005 à 14:01:58  profilanswer
 

En fait je m'en suis sorti (en créant un signal/slot intermédiaire)  
Donc oubliez mon précédent message ;)

n°1244886
i'n'i
Posté le 13-11-2005 à 23:09:46  profilanswer
 

Je reviens avec une nouvelle question ;)
Voilà ma classe "MaCase", il s'agit tout simplement d'une case avec une ellipse (cercle) blanche ou noire à l'interieur, que je dessine  
à la construction de ma case grâce au mécanisme PaintEvent
 
******************************
class MaCase : public QWidget
    {
    protected:
        void paintEvent(QPaintEvent *event);
    public:
       MaCase(int ligne, int colonne);
    }
 
MaCase::MaCase()
   {
    setFixedSize(84,84);
    setPalette(QPalette(QColor(40, 121, 17)));
   }
 
void MaCase::paintEvent( QPaintEvent * /* event */)
    {
     QPainter painter(this);
      painter.setPen(Qt::white);
      painter.setBrush(Qt::white);
   painter.drawEllipse(20,20,50,50);
       }
 
 
******************************
 
Ma question est toute simple : comment à partir d'un pointeur sur mon objet "MaCase" lui appliquer un changement de couleur de l'ellipse, lui faire redessiner une autre ellipse,... en bref appliquer des transformations de type "painter" sur ma "MaCase".
 
D'avance merci.
 

n°1245511
i'n'i
Posté le 14-11-2005 à 19:04:17  profilanswer
 

C'est bon, j'ai trouvé, il suffit de faire appel aux méthodes repaint() ou update() qui appellent la methode paintEvent() de la widget à redessiner.
 
Merci quand-même.
 

mood
Publicité
Posté le   profilanswer
 

 Page :   1  2
Page Suivante

Aller à :
Ajouter une réponse
 

Sujets relatifs
Plus de sujets relatifs à : c++ et Qt


Copyright © 1997-2025 Groupe LDLC (Signaler un contenu illicite / Données personnelles)