| auteur : Matthieu Brucher |
Dans un code Qt4, on verra souvent un new sans delete associé.
En fait, si une nouvelle instance de QObject est crée et qu'on lui spécifie un parent - le premier argument du constructeur -, c'est ce parent qui sera chargé de la destruction du fils.
La majorité des classes de Qt4 hérite plus ou moins directement de QObject, mais attention, ce n'est pas le cas de toutes. L'indicateur est la possiblité de passer un objet parent au constructeur.
|
lien : La classe QObject
|
| auteur : Matthieu Brucher |
Les signaux et slots sont l'implémentation par Trolltech du pattern observer. Ce pattern permet de prévenir les classes voulant observer un évènement.
Pour utiliser ce système, il faut hériter de QObject, soit directement, soit à l'aide d'un des objets dérivés de QObject. Ensuite, il faut définir la macro Q_OBJECT qui servira à qmake puis à moc pour générer le code nécessaire à l'utilisation de ces fonctions.
Pour déclarer des signaux, il suffit d'indiquer :
signal :
void monSignal ();
|
pour que moc génère le code qui va bien et pour que le signal puisse être utilisé. On appelera un signal par :
Ces signaux peuvent être connectés à d'autres signaux ou à des slots. Ces slots sont des fonctions du programmeur qui seront appelées dès que possible.
public slots:
void monSlot ();
|
Une fois les slots définis, il suffit de connecter les signaux et les slots entre eux. Comme il s'agit de connexion directe, il n'est pas possible de connecter un signal sans paramètre à un slot avec un paramètre. Pour cela, il faut utiliser entre-temps QSignalMapper.
connect (this , SIGNAL (monSignal (), somethingElse, SLOT (monSlot ()));;
|
On constatera aussi que signaux et slots ne peuvent pas retourner de valeur, pour l'instant.
|
lien : Les signaux et slots
lien : Tutoriel sur les signaux et slots de Qt 4
|
| auteur : Nykoo |
Dans la question "Les signaux et autres slots" nous avons vu comment s'interface une connexion entre signaux et slots simples, c'est à dire sans transmission de valeur.
Or, les signaux et slots ont la capacité de se transmettre des données par le biais de leurs arguments.
Prenons l'exemple de la classe QLineEdit de Qt.
Son signal textChanged(const QString&) permet de récupérer le texte présent dans le QLineEdit au moment de l'émission du signal.
De même, son slot setText(const QString&) permet de redéfinir le texte contenu dans le QLineEdit à l'aide d'un objet QString.
Rappel: Il est possible de connecter un signal avec un slot, mais on peut également connecter un signal à un autre signal.
Pour créer une connexion signal/slot (ou signal/signal) qui permette la transmission de valeurs,
il suffit d'écrire la signature complète de chaque signal/slot dans la fonction connect().
Autrement dit, il faut indiquer le nom des signaux/slots en question, ainsi que les types des arguments qu'ils prennent en paramètre :
Exemple de signature complète |
monSignal (QString,int )
monSlot (QString,int )
connect (objet1,SIGNAL (monSignal (QString,int )),objet2,SLOT (monSlot (QString,int )))
|
Attention, car il faut prendre certaines précautions. Dans une fonction connect(), les types des arguments des deux fonctions doivent être compatibles et placés dans le même ordre. Des arguments sont compatibles si le même objet est en jeux. Ex: const QString& est compatible avec QString. Par contre QString* et QString& ne le sont pas. Voici un exemple de connexion avec 2 types compatibles.
|
connect (this ,SIGNAL (monSignal (QString,int )),somethingElse,SLOT (monSlot (const QString& # 38 ; , int ) ) ) ;
|
Cependant, le signal ou le slot qui est situé dans la partie droite de la fonction connect() peut avoir un nombre d'arguments inférieur ou égal à celui du signal situé à gauche. Par exemple la connexion suivante:
|
connect (this ,SIGNAL (monSignal (QString,int )),somethingElse,SLOT (monSlot (QString)))
|
est valide. L'argument int sera simplement ignoré.
|
| auteur : Nykoo |
Cette question nécessite d'avoir compris la création de signaux/slots simples (sans arguments) décrite dans la question "Les signaux et autres slots"
Pour créer un signal ou un slot avec des arguments il suffit d'ajouter les noms des types dans le prototype:
|
class myClass : public xxx
{
Q_OBJECT
...
signals :
void monSignal (type1,type2)
public slots:
void monSlot (type1,type2);
...
}
|
Ainsi, pour émettre son signal il suffit d'utiliser le mot clef emit.
emmision du signal void monSignal(nom_type) |
void fonction ()
{
nom_type t;
emit monSignal (t);
}
|
La connexion se fera avec un signal ou un slot qui prend un argument de type nom_type.
|
| auteur : mac&cheese |
Sous Qt, les connexions entre les signaux et slots peuvent être mis en place soit manuellement, soit automatiquement, en utilisant la capacité qu'a QMetaObject d'établir des liens entre ces derniers.
Cette partie ne concerne pas les connexions manuelles (traitées à cette adresse), en revanche elle traite de la méthode automatique.
Bien qu'il soit plutôt aisé d'implémenter un slot et de le connecter dans le constructeur, nous pouvons tout aussi bien utiliser l'outil d'auto-connexion de QMetaObject pour connecter le signal clicked() de myButton à un slot dans notre classe.
Bien qu'il soit plutôt aisé d'implémenter un slot et de le connecter dans le constructeur, nous pouvons tout aussi bien utiliser l'outil d'auto-connexion de QMetaObject pour connecter les signals et les slot clicked() :
|
QMetaObject:: connectSlotsByName (QObject * object);
|
Cette fonction du QMetaObject de Qt connecte automatiquement tous slots qui respectent la convention on_Nomobjet_Nomsignal() au signal Nomsignal() correspondant de l'object Nomobjet. Deux conditions sont à remplir:
- L'objet NomObject doit être un enfant de l'objet passé en paramètre à la méthode connectSlotByName().
- Les objets (parents et enfants) doivent être nommés avec la fonction setObjectName(const QString& name).
exemple |
class MainWindows : public QWidget
{
Q_OBJECT
public :
MainWindows (QWidget * parent = 0 );
public slots :
void on_myButton_clicked ();
} ;
MainWindows:: MainWindows (QWidget * parent):QWidget (parent)
{
...
QPushButton * pButton = new QPushButton (" essai auto connect " );
pButton- > setObjectName (" myButton " );
...
QMetaObject:: connectSlotsByName (this );
}
|
Attention: supposons, cette fois-ci, que nous créons notre fenêtre via le Qt Designer et non plus en ligne de code; nous possédons alors un fichier supplémentaire,
à savoir, mainwindows.ui.
Lors de la compilation, l'outil uic de Qt, se charge de générer le code de la fonction setupUi() de notre fenêtre (mainwindows.ui).
Le code généré utilise alors de la même façon :
- setObjectName(const QString& name) : pour nommer les objets defini dans le *.ui
- QMetaObject::connectSlotsByName(QObject *object) : pour autoconnecter les objets définis dans le *.ui pendant l'appel à setupUi.
Il est donc possible d'utiliser de la meme façon, les auto-connexions sur une GUI codée à la main que sur une GUI créée à l'aide de Qt Designer (comment utiliser les *.ui)
REMARQUE: Si deux enfants ont le même nom, l'auto-connect ne se fera que sur le premier enfant trouvé.
REMARQUE2: Si QMetaObject::connectSlotsByName est appelé plusieurs fois, les connections générées seront multiples.
Lors de l'utilisation d'un *.ui, ne pas oublier que la fonction setupUi appel l'autoconnection
Voici deux exemples à télécharger :
|
| auteur : Matthieu Brucher |
Cette erreur se produit lorsque la partie QObject d'une classe n'a pas été ajoutée à l'édition des liens.
Lors de l'utilisation de la macro Q_OBJECT, on définit un certain nombre de méthodes et de variables statiques. Ces méthodes et ces variables sont implémentées dans un fichier généré automatiquement par qmake à l'aide de l'outil moc. Vous pouvez naturellement créer ce fichier manuellement et l'ajouter pour compilation et édition des liens.
|
lien : La classe QObject
lien : Les signaux et slots
|
| auteur : Yan Verdavaine |
Qt fournit la classz QProcess. Cette classz permet de contrôler l'exécution d'une application dans un nouveau process. Il est ainsi possible de contrôler :
- les variables d'environnements par la methode setEnvironement()
- le répertoire d'exécution par setWorkingDirectory()
- de lancer l'application par la fonction start
La fonction start qui crée un process enfant (sera fermé si le process parent est fermé) avec pour paramètres :
- path de l'exécutable
- liste des paramètres d'entrée de l'exe
- un mode d'ouverture pour interagir avec l'application par le biais des entréeé/sorties standard
Cette classe possède d'autres fonctions pour lancer une application :
- QProcess::execute : équivalent à start. Bloquante jusqu'à la fin de l'exécution de l'application lancée
- QProcess::startDetached : permet de lancer une application dans un process indépendant. Peut donner le pid du process créé
Il est bon de remarquer que ces fonctions:
- ont des paramètres similaires à ceux de start :
- path de l'exécutable
- liste des paramètres d'entrée de l'exe
- ne donne pas de moyen pour interagir avec le process par le biais des entrées/sorties standard
- ces deux fonctions sont des fonctions static et peuvent être appelées sans création d'un QProcess. Dans ce cas les variables d'environnement et le répertoire d'exécution sera le même que ceux de l'application courante.
Exemple utilisant QProcess::startDetached |
# include <QtGui>
class MyQPushButton : public QPushButton
{
public :
MyQPushButton (const QString & text,const QString & exe, QWidget * parent = 0 ):QPushButton (text,parent),m_exe (exe){ resize (75 , 30 );setFont (QFont (" Times " , 18 , QFont:: Bold));} ;
virtual void mouseReleaseEvent ( QMouseEvent * event )
{
QProcess:: startDetached (m_exe);
}
private :
QString m_exe;
} ;
int main (int argc, char * argv[])
{
QApplication app (argc, argv);
QWidget w;
QVBoxLayout vl (& w);
MyQPushButton bouton1 (" Ouvrir DVP / Qt " ," cmd /c start http://qt.developpez.com/ " ,& w);
MyQPushButton bouton2 (" Ouvrir notepad " ," notepad " ,& w);
MyQPushButton bouton3 (" Ouvrir invite de commande " ," cmd " ,& w);
vl.addWidget (& bouton1);
vl.addWidget (& bouton2);
vl.addWidget (& bouton3);
w.show ();
return app.exec ();
}
|
|
| auteur : Yan Verdavaine |
QProcess permet de lancer des applications externes ( voir ici). Elle permet surtout d'interagir avec l'application à la manière d'un pipe au travers des entrées/sorties standard de l'application.
Ainsi le troisième paramètre de la fonction start permet de spécifier quel type d'interaction on veut utiliser (par défaut, les deux types sont activés) :
- mode read : récupération de la sortie standard (stdout) et d'erreur(stderr)
- mode write : écriture sur l'entrée standard de l'application (stdin)
QProcess utilise les méthodes définies par QIODevice pour faire ces interactions. Pour la récuperation des sorties, il faut faire attention au channel que l'on est en train de lire :
- pour la sortie standard il faut utiliser : setReadChannel ( QProcess::StandardOutput )
- pour la sortie d'erreur il faut utiliser : setReadChannel ( QProcess::StandardError)
De plus Qprocess fournit deux signaux intéressants, qui indiquent si des données venant d'une des sortie sont arrivées :
- readyReadStandardOutput () : des données provenant de la sortie standards sont prêtes à être traitées
- readyReadStandardError () : des données provenant de la sortie d'erreur sont prêtes à être traitées
Il est aussi possible de faire ces interaction à l'aide de fichiers :
- setStandardErrorFile : fichier où l'on récupère la sortie d'erreur de l'application lancée
- setStandardOutput : fichier ou l'on récupère la sortie standard de l'application lancée
- setStandardInputFile : fichier contenant les donné à envoyer sur l'entrée standard de l'application lancée
|
| auteurs : Yan Verdavaine, IrmatDen |
Qt fournit la classe QDesktopServices et en particulier la fonction static QDesktopServices::openUrl, qui permet d'interagir avec les applications associées par défaut. Elle peut être étendue si nécessaire pour ajouter ses propres handlers pour un schéma donné.
|
# include <QtGui>
class MyQPushButton : public QPushButton
{
public :
MyQPushButton (const QString & text,const QString & url, QWidget * parent = 0 ):QPushButton (text,parent),m_url (url){ resize (75 , 30 );setFont (QFont (" Times " , 18 , QFont:: Bold));} ;
virtual void mouseReleaseEvent ( QMouseEvent * event )
{
QDesktopServices:: openUrl (m_url);
}
private :
QString m_url;
} ;
int main (int argc, char * argv[])
{
QApplication app (argc, argv);
QWidget w;
MyQPushButton bouton1 (" Ouvrir DVP / Qt " ," http://qt.developpez.com " ,& w);
MyQPushButton bouton2 (" Ouvrir fichier txt " ," c:/test.txt " ,& w);
MyQPushButton bouton3 (" Envoyer mail " ," mailto:qt@dvp.com?subject=test envoie mail " ,& w);
QVBoxLayout vl (& w);
vl.addWidget (& bouton1);
vl.addWidget (& bouton2);
vl.addWidget (& bouton3);
w.show ();
return app.exec ();
}
|
|
| auteur : IrmatDen |
Qt fournit la classe QLibrary permettant de charger de façon multi-plateformes une bibliothèque dynamique, ainsi que d'en récupérer des pointeurs vers les fonctions exportées.
Après avoir créé un objet de ce type, il faut spécifier le nom de la bibliothèque dynamique à associer sans préciser l'extension (ce n'est plus multi-plateformes sinon ). Il suffit ensuite d'appeler resolve() en fournissant le nom du symbole à trouver. Il est retourné en tant que void*, donc un cast sera bien évidemment nécessaire. Sont aussi fournies des fonctions statiques évitant l'instanciation dans le cas où l'on ne voudrait récupérer qu'un symbole.
Par exemple, admettons qu'une fonction d'une bibliothèque permette de compter le nombre de lettres dans un mot : |
typedef int (* StringLength)(char * );
QLibrary lib (" string_util " );
StringLength strLength = (StringLength)lib.resolve (" strlen " );
if (strLength)
strLength (" QLibrary " );
|
|
Consultez les autres F.A.Q's
Les sources présentés sur cette pages sont libre de droits,
et vous pouvez les utiliser à votre convenance. Par contre cette page de présentation de ces sources constitue une oeuvre intellectuelle protégée par les droits d'auteurs.
Copyright ©2006
Developpez LLC. Tout droits réservés Developpez LLC.
Aucune reproduction, même partielle, ne peut être faite de ce site et de
l'ensemble de son contenu : textes, documents et images sans l'autorisation
expresse de Developpez LLC. Sinon vous encourez selon la loi jusqu'à 3 ans
de prison et jusqu'à 300 000 E de dommages et intérets.
Cette page est déposée à la SACD.
|