| ||
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 possibilité de passer
un objet parent au constructeur.
| ||
lien : ![]() |
| ||||
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 :
pour que moc génère le code qui va bien et pour que le signal puisse
être utilisé. On appellera 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.
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.
On constatera aussi que signaux et slots ne peuvent pas retourner de
valeur, pour l'instant.
| ||||
lien : ![]() lien : ![]() |
| ||||||
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 :
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.
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:
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:
Ainsi, pour émettre son signal il suffit d'utiliser le mot clef emit.
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() :
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:
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 :
Il est donc possible d'utiliser de la même 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 : | ||||
téléchargement : Utilisation de autoconnect sans *.ui téléchargement : Utilisation de autoconnect avec *.ui |
| ||
auteur : kinji1 | ||
Qt propose de nombreuses classes avec de nombreux signaux déjà définis. Cependant
il peut parfois être intéressant de rajouter de l'information à ces signaux afin
de les paramétrer selon l'objet émetteur. On pourrait ainsi vouloir que différents
boutons réalisant une action commune, par exemple ouvrir une page web lorsque l'on
clique dessus, soient connecté à un même slot auquel on précise l'URL à utiliser.
Seulement le signal clicked() de la classe QPushButton ne transmet aucun paramètre,
ce qui ne permet pas de spécifier l'URL.
Une première solution consiste alors à connecter le signal clicked()
de chaque bouton à un slot différent qui se contentera d'appeler la fonction
d'ouverture de la page web avec l'url correspondante. Cependant, comme il est
nécessaire de créer un slot différent par bouton, cela rallonge inutilement la
taille du code, surtout lorsqu'il y a un grand nombre de boutons.
Une autre solution est d'utiliser la classe QSignalMapper. Dans notre exemple,
celle-ci va s'occuper d'appeler le slot ouvrant la page web avec un paramètre
configuré pour chacun des boutons (l'URL de la page). Nous avons donc d'un côté
les signaux clicked() des différents QPushButton, et de l'autre un slot
openUrl(const QString& url) et le QSignalMapper au milieu pour faire les correspondances.
Tout d'abord il faut créer un objet QSignalMapper, puis connecter les signaux
des boutons à son slot map(). On définit alors, pour chacun des boutons, le
paramètre à utiliser pour l'appel à openUrl via setMapping().
Enfin, il suffit de connecter le signal mapped de QSignalMapper à notre slot final.
Ainsi quand un bouton émettra son signal, le slot openUrl sera utilisé avec le paramètre
correspondant au bouton.
Note: QSignalMapper ne se limite pas à des paramètres de type QString. Il
est également possible d'utiliser des entiers ou encore des QWidget* et des QObject*.
Il faut dans ce cas utiliser le signal mapped correspondant au type que l'on veut transmettre.
|
| ||
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 : ![]() lien : ![]() |
| ||
auteur : Yan Verdavaine | ||
Qt fournit la classe QProcess. Cette classe permet de contrôler l'exécution d'une
application dans un nouveau process. Il est ainsi possible de contrôler :
La fonction start qui crée un process enfant (sera fermé si le process parent est
fermé) avec pour paramètres :
Cette classe possède d'autres fonctions pour lancer une application :
Il est bon de remarquer que ces fonctions:
|
| ||
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 standards 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) :
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 :
De plus Qprocess fournit deux signaux intéressants, qui indiquent si des données
venant d'une des sorties sont arrivées :
Il est aussi possible de faire ces interactions à l'aide de fichiers :
Attention : sous windows, un programme lisant l'entrée standard (stdin) en parallèle
de son ihm, peut se bloquer lorsqu'il est exécuté en process enfant. Ce bug est
normalement corrigé sous vista.
| ||
téléchargement : TestQProcess_zip |
| ||
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é.
|
| ||
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 :
|
| ||
auteur : Yan Verdavaine | ||
Une grosse partie de Qt est basé sur le COW. Il permet ainsi d'utiliser ce pattern.
Pour cela, il faut créer une classe héritant de QSharedData est possédant un constructeur,
un constructeur par recopie et un destructeur public. Cette classe sera l'objet
interne qui sera partagé. Elle possède un compteur de référence thread safe et ne doit
pas être directement accédé. Sa vie sera gérée par d'autres classes.
Pour accéder à une instance de cette classe, deux choix sont possible :
Ces deux classes sont des pointeurs intelligents
spécialisé sur la manipulation des pointeurs sur QSharedData. Ils implémentent
donc la sémantique des pointeurs avec des accès const (lecture) et non const (écriture).
Elles détruiront le QSharedData une fois son compteur à zéro.
Ces pointeurs intelligents possèdent deux fonctions qu'il est utile de connaitre :
Remarque : ces classes sont thread safe
| ||
lien : ![]() lien : ![]() lien : ![]() |
| ||
auteur : François Jaffré | ||
Les timers sont gérés avec Qt à l'aide de la classe QTimer. Cette classe est
relativement simple à utiliser grâce aux méthodes suivantes :
Remarque 1 : Si vous souhaitez utiliser un timer en mode "single shot" QTimer possède une methode static QTimer::singleShot() qui peut vous être très utile.
Remarque 2 : Un timer n'est jamais très précis et est fortement dépendant de l'OS. Si vous souhaitez être précis à la milliseconde près ce n'est pas la solution à utiliser. | ||
lien : ![]() lien : ![]() |
| ||
auteur : François Jaffré | ||
La classe QTime permet de récupéré l'heure du PC facilement à l'aide de la méthode static suivantes :
| ||
lien : ![]() |
| ||
auteur : François Jaffré | ||
QTime fournit la méthode elapsed() qui permet de connaitre le temps écoulé (en ms)
entre l'exécution de la méthode start() ou restart() et l'appel à la fonction elapsed().
Remarque : Si vous voulez vraiment mesurer précisément votre code et faire
du benchmarking de votre application alors il est préférable de vous tournez vers la
QTestLib qui est faite pour ça.
| ||
lien : ![]() lien : ![]() |
| |||
auteur : Louis du Verdier | |||
Dans les années 1980 à 1990 (aucune information ne précise la date exacte), la fonction main() ne renvoyait rien, elle était donc de type void.
Plus récemment, des améliorations de cette fonction ont introduit les arguments qui sont en fait dans la norme actuelle de mettre "int argc" et "char *argv[]".
Ces arguments sont complémentaires : "char *argv[]" représente un tableau de pointeurs de taille donnée par "int argc". Sur la plupart des systèmes d'exploitation,
le tout sert par exemple à retrouver le chemin du programme lancé (avec argv[0]), ou encore par exemple à retrouver un fichier par lequel s'est ouvert le programme
(argc serait donc supérieur à 1).
Quel rapport avec Qt ? Et bien la bibliothèque permet de récupérer les arguments à l'aide de la fonction QCoreApplication::arguments.
La récupération sert par exemple à récupérer le chemin d'un éventuel fichier ouvert par clic sur l'icône de celui-ci.
Note : Lors de la déclaration de la fonction main, il faut mettre les arguments pour que ce qui est donné marche, c'est à dire utiliser un début de code comme celui-ci pour la fonction main :
Remarque : En règle générale, le premier élément correspond au nom de l'exécutable. Suivant la plateforme et la mode d'exécution, cet élément peut aussi contenir le chemin relatif ou le chemin absolu de l'exécutable concaténé avec son nom.
Voici un exemple permettant de clore :
Attention : Sous mac, le double-clic sur un fichier ne sera pas renseigné dans les arguments, contrairement à Windows et Linux. Pour cela il faut utiliser QFileOpenEvent.
| |||
lien : ![]() |
Les sources présentées sur cette page sont libres de droits et vous pouvez les utiliser à votre convenance. Par contre, la page de présentation constitue une œuvre intellectuelle protégée par les droits d'auteur. Copyright © 2006 Developpez Developpez LLC. Tous droits réservés Developpez LLC. Aucune reproduction, même partielle, ne peut être faite de ce site ni de l'ensemble de son contenu : textes, documents et images sans l'autorisation expresse de Developpez LLC. Sinon vous encourez selon la loi jusqu'à trois ans de prison et jusqu'à 300 000 € de dommages et intérêts.