IdentifiantMot de passe
Loading...
Mot de passe oublié ?Je m'inscris ! (gratuit)
logo
Sommaire > Le contenu de Qt4 > QtCore
        Un new sans delete ?
        Les signaux et autres slots ?
        Comment s'interfacent les signaux et les slots?
        Comment créer ses propres signaux et slots avec transmission de valeurs?
        Comment utiliser les auto-connexions ?
        Comment paramétrer un slot selon les objets qui lui sont connectés ?
        Erreur d'édition des liens undefined reference to 'vtable for xxx' ?
        Comment ouvrir une application à partir de Qt ?
        Comment interagir avec une application lancée par un QProcess?
        Comment interagir avec les applications associées par défaut ?
        Comment charger et utiliser dynamiquement une .dll, .so avec Qt ?
        Comment optimiser la copie de ses classes ?
        Comment utiliser un QTimer ?
        Comment récupéré l'heure du PC ?
        Comment mesurer un intervalle de temps ?
        Comment récupérer les arguments envoyés par la fonction main ?
        3.1.1. QObject (2)
                Allouer sur le tas ou sur la pile des QObject et dérivés ?
                Héritage multiple avec QObject ?
        3.1.2. QString (10)
                Faut-il utiliser les pointeurs avec QString ?
                Transformer un QString en std::string et réciproquement ?
                Comment convertir un QString en chaîne C (char *) ?
                Formatage de texte avec QString ?
                Comment convertir un nombre en chaîne de caractère ?
                Comment formater les nombres entiers ?
                Conversion QString vers nombre ?
                Comment formater les nombres réels ?
                Comment tester si une chaîne de caractère est vide ?
                Comment QString gère l'encodage des chaînes de caractères ?
        3.1.3. Thread (7)
                Pourquoi ne faut-il pas faire de traitement IHM dans un thread ?
                comment est définie l'appartenance aux threads des objets Qt ?
                comment utiliser les threads avec Qt ?
                comment fonctionne QThread ?
                Comment se passe un connect entre thread ?
                Comment manipuler un mutex ?
                Comment faire une pause dans une QThread ?
        3.1.4. Fichiers et repertoires (11)
                Comment effacer un fichier ?
                Comment vérifier si un fichier existe ?
                Comment copier un fichier ?
                Comment récupérer le chemin des répertoires spéciaux ?
                Comment sélectionner un nom de fichier ou répertoire à partir d'une boite de dialogue ?
                Comment lister les fichiers d'un répertoire et de ses sous répertoires ?
                Comment écrire dans un fichier texte ?
                Comment lire dans un fichier texte ?
                Comment écrire et lire dans un fichier binaire ?
                Comment connaitre le chemin du répertoire courant ?
                Comment récupérer le chemin du répertoire de l'exécutable ?



Un new sans delete ?
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 : en La classe QObject

Les signaux et autres slots ?
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 appellera un signal par :

   emit monSignal();
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 : en Les signaux et slots
lien : fr Tutoriel sur les signaux et slots de Qt 4

Comment s'interfacent les signaux et les slots?
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) //signature d'un signal
monSlot(QString,int) //signature d'un slot
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&,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é.


Comment créer ses propres signaux et slots avec transmission de valeurs?
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.
Emmission 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.


Comment utiliser les auto-connexions ?
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 QString.
exemple

class MainWindows : public QWidget
{
    Q_OBJECT
public :
    MainWindows(QWidget * parent = 0);
 
public slots :
    //slot qui sera connecté au signal clicked de l'objet myButton
    //par l'autoconnect
    void on_myButton_clicked();
 
};

MainWindows::MainWindows(QWidget * parent):QWidget(parent)
{
    ...
    QPushButton * pButton = new QPushButton("essai auto connect");
    //nom du bouton pour être retrouvé par l'autoconnect
    pButton->setObjectName("myButton");
    ...
    //auto connection des signaux/slots
    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 :

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

Comment paramétrer un slot selon les objets qui lui sont connectés ?
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().
mapper = new QSignalMapper();
 
// Bouton 1
connect(bouton1, SIGNAL(clicked()), mapper, SLOT(map()));
mapper->setMapping(bouton1, "http://url1");
 
// Bouton 2
connect(bouton2, SIGNAL(clicked()), mapper, SLOT(map()));
mapper->setMapping(bouton2, "http://url2");
 
// Autres boutons ?
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.
connect(mapper, SIGNAL(mapped(const QString &)), this, SLOT(openUrl(const QString &)));
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.


Erreur d'édition des liens undefined reference to 'vtable for xxx' ?
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 : en La classe QObject
lien : en Les signaux et slots

Comment ouvrir une application à partir de Qt ?
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 :

  • les variables d'environnements par la méthode 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ées/sorties standards
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 standards
  • 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 :
    //createur.
    //text : text du bouton
    //exe  : commande à exécuter lors de l'appui.
    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 )
    {
        //lance la commande dans un process indépendant
        QProcess::startDetached (m_exe);
    }

    private :
        QString m_exe;

};

int main(int argc, char* argv[])
{
    QApplication app(argc, argv);
    QWidget w;
    QVBoxLayout vl(&w);
    //boutton : ouvre grâce au CMD la page vers DVP/Qt
    MyQPushButton bouton1("Ouvrir DVP / Qt","cmd /c start http://qt.developpez.com/",&w);

    //boutton : lance notepad
    MyQPushButton bouton2("Ouvrir notepad","notepad",&w);

     //boutton : lance invite de commande
    MyQPushButton bouton3("Ouvrir invite de commande","cmd" ,&w);
    vl.addWidget(&bouton1);
    vl.addWidget(&bouton2);
    vl.addWidget(&bouton3);
    w.show();
    return app.exec();
}

Comment interagir avec une application lancée par un QProcess?
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) :

  • 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 :

De plus Qprocess fournit deux signaux intéressants, qui indiquent si des données venant d'une des sorties 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 interactions à 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
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

Comment interagir avec les applications associées par défaut ?
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 :
    //createur.
    //text : texte du boutton
    //exe  : commande à executer lors de l'appui.
    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;
   
    //Action : ouvre l'url ver DVP /Qt
    MyQPushButton bouton1(" Ouvrir DVP / Qt","http://qt.developpez.com",&w);
    //Action : ouvre le fichier texte. /!\ ce fichier doit exister
    MyQPushButton bouton2("Ouvrir fichier txt","c:/test.txt",&w);
    //Action : ouvre l'edition d'un mail avec l'adresse et le sujet remplis
    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();
}

Comment charger et utiliser dynamiquement une .dll, .so avec Qt ?
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 :
// définition du type de fonction
typedef int (*StringLength)(char*); 
// création d'un objet QLibrary lié à string_util (.dll, .so ou autre)
QLibrary lib("string_util"); 
// récupération d'un pointeur sur notre fonction partagée
StringLength strLength = (StringLength)lib.resolve("strlen"); 
if(strLength)
// devrait renvoyer 9... si tout va bien  ;) 
    strLength("QLibrary"); 

Comment optimiser la copie de ses classes ?
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 :

  • QSharedDataPointer: permet de partager implicitement un QSharedData. L'objet interne est partagé en lecture. L'accès à l'objet en écriture va générer une recopie de l'objet.
  • QExpliciteSharedDataPointer : permet de partager explicitement un QSharedData. L'objet interne est partagé en lecture/écriture. L'objet interne sera recopié uniquement sur demande.
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 :

  • Detach() : Si le compteur de référence est > 1, le QSharedData sera copié
  • Reset() : Initialise à null le pointeur intelligent
Remarque : ces classes sont thread safe

lien : faq Comment Qt optimise t il les copies ?
lien : fr Faq C++ : pointeurs intelligents
lien : fr Tutoriel : Pointeurs intelligents

Comment utiliser un QTimer ?
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 :

  • int interval () const -> Permet de connaitre l'intervalle de temps (en ms) entre chaque déclanchement du timer.
  • bool isActive () const -> Permet de connaitre si le timer est activé ou pas.
  • bool isSingleShot () const -> Permet de connaitresi le timer est en déclanchement unique ou pas.
  • void setInterval ( int msec ) -> Permet de paramétrer l'intervalle (en ms) entre chaques déclanchements du timer
  • void setSingleShot ( bool singleShot ) -> Permet de mettre le timer en mode déclanchement unique
  • void start() -> Permet de démarrer le timer
  • void stop() -> Permet d'arrêter le timer
Création d'un chronomètre simple précis à la seconde

#include <QApplication>
#include <QLCDNumber>
#include <QPushButton>
#include <QTimer>
#include <QGridLayout>
 
class TimerChrono : public QWidget
{
    Q_OBJECT
 
private :
    //Bouton servant de "Start" "Stop"
    QPushButton* m_Bouton_StartStop;
    //Bouton "Reset"
    QPushButton* m_Bouton_Reset;
    //Afficheur de type LCD
    QLCDNumber* m_LCD;
    //Variable représentant le nombre de secondes écoulées depuis le lancement du timer
    int m_Timer_value;
    //Timer servant de base à notre Chronomètre
    QTimer* m_timer;
    //Permet de savoir si l'utilisateur a cliqué sur "Start" ou "Stop"
    bool validStart;
 
public :
    TimerChrono()
    {
        //Creation d'un afficheur LCD de 5 digits maximum
        this->m_LCD = new QLCDNumber(5, this);
        //Creation des contrôles de types boutons
        this->m_Bouton_StartStop = new QPushButton("Start",this);
        this->m_Bouton_Reset = new QPushButton("Reset",this);
        
        //Gestion du layout pour le placement des boutons
        QGridLayout *layout = new QGridLayout();
        layout->addWidget(m_LCD, 0, 0);
        layout->addWidget(m_Bouton_StartStop, 2,0);
        layout->addWidget(m_Bouton_Reset, 2,1);
        this->setLayout(layout);
         
        //On met à zeros le compteur représentant le nombre de seconde
        this->m_Timer_value=0;
        //Création du timer
        this->m_timer = new QTimer(this);
        //A chaque fin d'interval execution de la fonction update()
        connect(this->m_timer, SIGNAL(timeout()), this, SLOT(update()));
        //On applique un interval d'une seconde (1000 ms) entre chaque timeout du timer
        this->m_timer->setInterval(1000);
        //Sert pour la gestion du bouton "Start" "Stop"
        this->validStart=true;
        
        //On connecte les differents signaux et slots
        connect(this->m_Bouton_StartStop, SIGNAL(clicked(bool)), this, SLOT(click_StartStop(bool)));
        connect(this->m_Bouton_Reset, SIGNAL(clicked(bool)), this, SLOT(click_Reset(bool)));
         
         //Gestion de la taille de la fenêtre
        resize(200, 150); 
    }
 
private slots:
    //Fonction appellée toute les secondes par le QTimer
    void update()
    {
        //On incremente notre compteur de secondes
        m_Timer_value++;
        //On affiche le nombre de seconde ecoulé dans le contrôle QLCDNumber
        m_LCD->display(m_Timer_value);
    }
 
    //Bouton reset
    void click_Reset(bool valid)
    {
        // On arrete le timer
        this->m_timer->stop();
        //On met notre compteur à zero
        m_Timer_value=0;
        // On affiche Zero dans le controle LCD
        m_LCD->display(m_Timer_value);
        //Gestion du bouton "Start" "Stop"
        this->validStart=true;
        m_Bouton_StartStop->setText("Start");
    }

    //Bouton "Start" "Stop"
    void click_StartStop(bool valid)
    {
        //Si on click sur "Start"
        if(validStart == true)
        {
            //Affiche "Stop" sur le bouton
            m_Bouton_StartStop->setText("Stop");
            //Permet de savoir que le bouton est en mode "Strop"
            validStart = false;
            //On declanche le départ du Timer
            this->m_timer->start();
        }
        else//Si on click sur "Stop"
        {
            //Affiche "Sart" sur le bouton
            m_Bouton_StartStop->setText("Start");
            //Permet de savoir que le bouton est en mode "Start"
            validStart = true;
            //On arrete le compteur
            this->m_timer->stop();
        }
    }
}; 
 
#include "main.moc"
 
int main(int argc, char *argv[])
{
    QApplication a(argc, argv);
    TimerChrono w;
    w.show();
    return a.exec();
}
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 : en QTimer
lien : en QTimer::SingleShot

Comment récupéré l'heure du PC ?
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 :

//L'objet time est initialisé à l'heure courante
QTime time = QTime::currentTime();
lien : en QTime

Comment mesurer un intervalle de temps ?
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().
QTime time;
time.start();
ma_fonction();
//millisecondes contient le nombre de millisecondes entre l'appel à la fonction start() 
//et l'appel a la fonction elapsed().
int millisecondes = time.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 : en QTime
lien : en QTestLib

Comment récupérer les arguments envoyés par la fonction main ?
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.
QStringList args = QCoreApplication::arguments();
QString nom_fichier = args[1];
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 :

int main (int argc, char *argv[])
{
    QApplication app(argc,argv)
    // Suite du code
}
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 :
const QStringList args = QCoreApplication::arguments();
// Si le programme a été ouvert par le biais d'un fichier
if(args.count() > 1) 
{
    // On récupère le chemin du fichier...
    QString nom_fichier = args[1]; 
    // ... et on appelle une éventuelle fonction de lecture
    lireFichier(nom_fichier, this); 
}
// ...
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 : en QFileOpenEvent


Consultez les autres F.A.Q's


Valid XHTML 1.1!Valid CSS!

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.