Qt Jambi : émettre un signal

On peut bien sûr utiliser les signaux existants, mais ça peut-être intéressant d'émettre des signaux entre ses propres objets. Heureusement pour nous, avec Qt Jambi c'est très facile. Voyez plutôt...

35 commentaires Donner une note à l'article (5)

Article lu   fois.

Les deux auteurs

Liens sociaux

Viadeo Twitter Facebook Share on Google+   

I. Qu'est-ce que c'est un signal ?

Un signal est un objet qui est défini comme attribut public d'une classe (c'est assez rare d'avoir un attribut public pour le préciser). Cet objet contient deux méthodes publiques principales :

  • connect : connecter une méthode (slot) à ce signal ;
  • emit : émettre un signal.

Un signal peut émettre avec lui des variables en Java entre zéro et neuf variables. Le nom du signal dépend de ce nombre de variables que l'on veut envoyer. Voici comment on ajoute un signal à notre classe :

 
Sélectionnez
public Signal1<Integer> valueChanged = new Signal1<Integer>();

Comme vous le comprendrez sûrement, ce signal émet avec lui un entier (Integer). C'est le signal de LCDNumber. Et voilà, un signal, ce n'est rien de plus que ça.

II. Émettre un signal

Pour qu'un signal soit utile, il faut un jour ou l'autre l'émettre. Cela veut dire qu'on active la connection avec le slot. Autant se donner un but.

II-A. Cahier de charges

On va commencer par créer un nouveau widget qui contiendra un champ de texte QLineEdit ainsi qu'un QLabel. Notre objet, lorsque le texte du QLineEdit va être changé, va émettre un signal. Ainsi, il pourra modifier le texte d'une autre boîte de dialogue (un minichat entre deux boîtes de dialogue). Ça va ressembler à ça :

Chat inter Dialog

Étant donné que QLineEdit s'occupe déjà de nous envoyer un signal, on ne va faire que le retransmettre.

 
Sélectionnez
import com.trolltech.qt.gui.*;
 
public class DialogButton extends QDialog {
        private QLabel text;
        
        public final Signal1<String> configured = new Signal1<String>();
        
        public DialogButton(String titre){
                QLabel label = new QLabel(tr("Entrez votre message:"));
                QLineEdit lineEdit = new QLineEdit();
                text = new QLabel();
                QVBoxLayout layout = new QVBoxLayout( this );
                layout.addWidget(label);
                layout.addWidget(lineEdit);
                layout.addWidget(text);
                setLayout(layout);
                setWindowTitle(titre);
                lineEdit.textChanged.connect(this, "emit(String)");
        }
        
        public void emit(String s){
                configured.emit(s);     
        }
        
        public void write(String lineEditText){
                if(text.text() != lineEditText){
                        text.setText(lineEditText);     
                }
        }
        
        public static void main(String[] args){
                QApplication.initialize(args);
                DialogButton app = new DialogButton("Dialog 1");
                DialogButton ap2 = new DialogButton("Dialog 2");
                app.configured.connect(ap2, "write(String)");
                ap2.configured.connect(app, "write(String)");
                app.show();
                ap2.show();
                QApplication.exec();
        }       
}

Regardons de plus près :

 
Sélectionnez
public final Signal1<String> configured = new Signal1<String>();

On ajoute un signal configured à notre widget, qui va émettre avec lui une chaîne de caractères qui sera le contenu du LineEdit.

 
Sélectionnez
lineEdit.textChanged.connect(this, "emit(String)");

Ici, on connecte le signal reçu du lineEdit quand le texte a changé avec notre méthode emit, qui va émettre notre signal.

 
Sélectionnez
public void emit(String s){
      configured.emit(s);     
}

La méthode emit() va seulement émettre notre signal configured.

 
Sélectionnez
public void write(String lineEditText){
       if(text.text() != lineEditText){
                text.setText(lineEditText);     
       }
}

Dans la méthode write, on vérifie que le texte a bien changé. C'est une simple précaution pour éviter des boucles qui pourraient provoquer des scintillements de l'interface ou une augmentation indésirable de l'activité du processeur. On ne sait en effet pas quels sont les mécanismes mis en place par la méthode setText. Donc, par précaution (sûrement inutile dans ce cas), on évite des calculs inutiles. Dans la méthode main, on crée des boîtes de dialogue que l'on nomme pour les différencier. On connecte le signal de l'une avec la méthode write de l'autre et vice-versa. Maintenant, il est temps de tester.

III. Petit exercice

III-A. Énoncé

En reprenant le résultat de l'exercice précédent, on souhaite, lorsqu'on modifie un slider, modifier les états de tous les sliders précédents.

III-B. Résultat

Un signal récursif...

III-C. Question subsidiaire

Définir l'ordre dans lequel ont été modifiés les sliders de la boîte de dialogue du screenshot. Pour cela, on numérotera les sliders : (0,0) pour le premier, (0,1) pour le deuxième, (2,0) pour le premier de la troisième ligne, etc.

IV. Remerciements

Merci à Thibaut Cuvelier pour la mise en page et à Jacques Thery pour la relecture !

Qt en Java avec Qt Jambi
Du Qt en Java avec Qt Jambi
Utiliser Qt avec Java
Codons notre première fenêtre
Disposer les choses
Une boîte de dialogue
Une application avec des menus et des barres d'outils
Connecter les objets entre eux
Émettre un signal
JEditor, un simple éditeur de fichier texte
JViewer, un lecteur d'image
Image non disponible