IdentifiantMot de passe
Loading...
Mot de passe oublié ?Je m'inscris ! (gratuit)
Navigation

Inscrivez-vous gratuitement
pour pouvoir participer, suivre les réponses en temps réel, voter pour les messages, poser vos propres questions et recevoir la newsletter

Réseau Discussion :

Interface Web pour un logiciel Qt


Sujet :

Réseau

  1. #1
    Membre confirmé

    Homme Profil pro
    Étudiant
    Inscrit en
    Avril 2011
    Messages
    532
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 34
    Localisation : France, Isère (Rhône Alpes)

    Informations professionnelles :
    Activité : Étudiant
    Secteur : Enseignement

    Informations forums :
    Inscription : Avril 2011
    Messages : 532
    Points : 604
    Points
    604
    Par défaut Interface Web pour un logiciel Qt
    Bonjour à toutes et à tous,

    Je sollicite votre aide car je me heurte actuellement à un problème que je n'arrive pas à résoudre. Voici mon problème:

    Je viens de développer un petit logiciel grâce à Qt qui me permet de créer une communication série entre mon pc et un automate (via un câble USB/RS485) et qui me permet d'allumer des LEDs qui sont connectés sur les sorties TOR de mon automate. Mon logiciel marche parfaitement.

    Le but final de ce logiciel est de devenir un logiciel embarqué sur une carte Raspberry Pi (ayant linux comme OS) qui prendra le rôle de mon pc dans l'avenir. Sur cette carte, en plus de mon logiciel, est installé un serveur web embarqué (lighttpd). Maintenant, ce que je vais faire c'est qu'au lieu d'utiliser l'IHM que j'ai développé lors de la conception de mon logiciel, je veux utiliser une IHM que sera sur une page web et qui pourra faire exactement comme l'IHM "de base". Le problème c'est: comment faire ???

    Je suis ouvert à toutes les propositions

    Cordialement,
    Clairetj

  2. #2
    Responsable Systèmes


    Homme Profil pro
    Gestion de parcs informatique
    Inscrit en
    Août 2011
    Messages
    17 730
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Paris (Île de France)

    Informations professionnelles :
    Activité : Gestion de parcs informatique
    Secteur : High Tech - Matériel informatique

    Informations forums :
    Inscription : Août 2011
    Messages : 17 730
    Points : 43 837
    Points
    43 837
    Par défaut interfaçage web
    Ca fait qq jours que je voit tes posts.

    Es-tu sûr que c'est Qt qu'il te faut, si c'est piloter ton port série via une interface http, de simples scripts cgi ne feraient t'ils pas l'affaire ?

  3. #3
    Membre confirmé

    Homme Profil pro
    Étudiant
    Inscrit en
    Avril 2011
    Messages
    532
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 34
    Localisation : France, Isère (Rhône Alpes)

    Informations professionnelles :
    Activité : Étudiant
    Secteur : Enseignement

    Informations forums :
    Inscription : Avril 2011
    Messages : 532
    Points : 604
    Points
    604
    Par défaut
    Alors pour le choix de Qt, déjà, moi je fait une poursuite du projet de mon prédécesseur qui avait choisi Qt pour la portabilité (utilisable sur Linux, Windows, etc ...). Ensuite le programme que j'ai fait rester relativement simple parce que ce n'est qu'une "prise en main" pour trouver justement la solution de comment faire pour avoir une interface web parce que par la suite le programme sera beaucoup plus imposant et compliqué et ce programme sera lui aussi développé sous Qt, c'est pour cela que je souhaite garder Qt

  4. #4
    Membre éclairé
    Profil pro
    Inscrit en
    Février 2009
    Messages
    383
    Détails du profil
    Informations personnelles :
    Localisation : Belgique

    Informations forums :
    Inscription : Février 2009
    Messages : 383
    Points : 658
    Points
    658
    Par défaut
    Rien ne sert de créer 3 posts... si des personnes ont des idées, ils les donneront.

    Bon, en gardant ton application Qt et en revenant sur ce que je t avais soumis dans l autre post.

    en gros, tu communiquerais avec ton application en appelant ton logiciel comme ceci :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    ./myprogram start_something
    ./myprogram end_something
    ./myprogram action_of_my_button
    Dans ton programme, tu t'arranges pour garder une seule instance.
    On peut faire ca avec QLocalServer et QLocalSocket.

    Dans ton main:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
        SingleInstanceApplication a("MY_SOFTWARE", argc, argv); //  MY_SOFTWARE = identifiant de ton application
     
        if(!a.isMainInstance()){
            qDebug() << "already launched";
            return 0;
        }
     
        ... sinon on continue ...
    Et pour le constructeur de class SingleInstanceApplication:
    (je te laisse cogiter sur les fonctions localServerHasNewConnection, sendArgumentsToMainInstance... et la fonction qui recoit les donnees (en utilisant le signal "readyRead") ... )
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    SingleInstanceApplication::SingleInstanceApplication(const QString &localName, int &argc, char **argv) :
        QApplication(argc, argv),
        m_isMainInstance(false)
    {
        m_socket = new QLocalSocket();
        m_socket->connectToServer(localName);
        // on essaie de se connecter a un potentiel serveur local
        if(m_socket->waitForConnected(100)){
            // ca a fonctionné... donc il existe deja une instance de notre logiciel
            QThread::msleep(50);
            // ex: ca envoi "action_of_my_button" a l instance principale
            sendArgumentsToMainInstance(argv);
            // on ferme la connection.
            m_socket->close();
        } else {
            // ca ne fonctionne pas, donc il n y a pas encore d instance principale... 
            m_isMainInstance = true;
            m_localServer = new QLocalServer(this);
            connect(m_localServer, &QLocalServer::newConnection, this, &SingleInstanceApplication::localServerHasNewConnection);
            m_localServer->listen(localName);
        }
    ...
    }
    Maintenant, évite de créer d'autres posts sur le meme sujet ... sinon les personnes qui recherchent la même chose que toi n'auront jamais leur réponse.

  5. #5
    Membre confirmé

    Homme Profil pro
    Étudiant
    Inscrit en
    Avril 2011
    Messages
    532
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 34
    Localisation : France, Isère (Rhône Alpes)

    Informations professionnelles :
    Activité : Étudiant
    Secteur : Enseignement

    Informations forums :
    Inscription : Avril 2011
    Messages : 532
    Points : 604
    Points
    604
    Par défaut
    Citation Envoyé par RapotOR Voir le message

    Et pour le constructeur de class SingleInstanceApplication:
    (je te laisse cogiter sur les fonctions localServerHasNewConnection, sendArgumentsToMainInstance... et la fonction qui recoit les donnees (en utilisant le signal "readyRead") ... )

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
     
    SingleInstanceApplication::SingleInstanceApplication(const QString &localName, int &argc, char **argv) :
        QApplication(argc, argv),
        m_isMainInstance(false)
    {
        m_socket = new QLocalSocket();
        m_socket->connectToServer(localName);
        // on essaie de se connecter a un potentiel serveur local
        if(m_socket->waitForConnected(100)){
            // ca a fonctionné... donc il existe deja une instance de notre logiciel
            QThread::msleep(50);
            // ex: ca envoi "action_of_my_button" a l instance principale
            sendArgumentsToMainInstance(argv);
            // on ferme la connection.
            m_socket->close();
        } else {
            // ca ne fonctionne pas, donc il n y a pas encore d instance principale... 
            m_isMainInstance = true;
            m_localServer = new QLocalServer(this);
            connect(m_localServer, &QLocalServer::newConnection, this, &SingleInstanceApplication::localServerHasNewConnection);
            m_localServer->listen(localName);
        }
    ...
    }
    Donc en plus de ma class MainWindow, je crée une nouvelle classe et c'est cette nouvelle classe qui va me permettre d'interférer avec ma page web c'est ça ?

  6. #6
    Membre confirmé

    Homme Profil pro
    Étudiant
    Inscrit en
    Avril 2011
    Messages
    532
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 34
    Localisation : France, Isère (Rhône Alpes)

    Informations professionnelles :
    Activité : Étudiant
    Secteur : Enseignement

    Informations forums :
    Inscription : Avril 2011
    Messages : 532
    Points : 604
    Points
    604
    Par défaut
    Et comme tu me l'as demandé j'ai commencé à cogiter pour les fonctions localServerHasNewConnexion, sendArgumentsToMainInstance et je dois avouer que je galère vraiment. Voilà où j'en suis actuellement:

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
     
    void SingleInstanceApplication::localServerHasNewConnexion()
    {
        if(QLocalServer::newConnection())
        {
            identificateurClient = new QLocalSocket();
            identificateurClient = QLocalServer::nextPendingConnection();
            nomClient = new QString();
            nomClient = QLocalServer::serverName();
        }
    }
     
     
    void SingleInstanceApplication::sendArgumentsToMainInstance(argv)
    {
        connect(bouton_interface_web, SIGNAL(&QLocalSocket::stateChanged), this, SLOT(bouton_interface_programme)); 
    }
    Je sais que j'aurais des erreurs (notamment avec sendArgumentsToMainInstance) mais à défaut de me donner la solution, est-ce que tu peux au moins me dire si il y a de l'idée dans ce que je fais ou si j'ai rien compris et que je vais dans le mur svp ?

  7. #7
    Membre éclairé
    Profil pro
    Inscrit en
    Février 2009
    Messages
    383
    Détails du profil
    Informations personnelles :
    Localisation : Belgique

    Informations forums :
    Inscription : Février 2009
    Messages : 383
    Points : 658
    Points
    658
    Par défaut
    Je ne vois pas trop à quoi serve les lignes suivantes :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    nomClient = new QString();
    nomClient = QLocalServer::serverName();
    Sinon, a cet endroit; tu peux connecter le signal readyRead à un slot de ta classe. Ainsi l'instance principale (qui possede le QLocalServer) récupére l'info quand elle arrive.

    Dans ta fonction "sendArgumentsToMainInstance", j'aurais plutot envoyé les arguments (example : http://qt-project.org/doc/qt-5.0/qtc...e.html#write-2) comme un QIODevice vu que le QLocalSocket en hérite.

  8. #8
    Membre confirmé

    Homme Profil pro
    Étudiant
    Inscrit en
    Avril 2011
    Messages
    532
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 34
    Localisation : France, Isère (Rhône Alpes)

    Informations professionnelles :
    Activité : Étudiant
    Secteur : Enseignement

    Informations forums :
    Inscription : Avril 2011
    Messages : 532
    Points : 604
    Points
    604
    Par défaut
    Pour ce qui est de la fonction sendArgumentsToMainInstance, j'avais effectivement penser au départ utiliser
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    QLocalSocket::writeData()
    qui comme l'explique la doc est une Réimplémentation de QIODevice::writeData(). (donc ce que tu m'explique) mais si j'ai changer pour mettre mon connect c'est parce que je ne voyais pas quoi passer en paramètres donc se pourrait-il que ce que je passe en paramètre dans mon QLocalSocket::writeData() soit argv que je donne en paramètre lorsque j'appelle sendArgumentsToMainInstance ?

  9. #9
    Membre confirmé

    Homme Profil pro
    Étudiant
    Inscrit en
    Avril 2011
    Messages
    532
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 34
    Localisation : France, Isère (Rhône Alpes)

    Informations professionnelles :
    Activité : Étudiant
    Secteur : Enseignement

    Informations forums :
    Inscription : Avril 2011
    Messages : 532
    Points : 604
    Points
    604
    Par défaut
    Je fais un petit point pour montrer ce que j'ai tapé pour l'instant. Donc dans mon fichier .h j'ai rajouté:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    class SingleInstanceApplication
    {
    public:
           SingleInstanceApplication(const QString &localName, int &argc, char **argv);
           ~SingleInstanceApplication();
     
    private slots:
           void localServerHasNewConnexion();
           void sendArgumentsToMainInstance(char argv);
           void receiveData(char argv);
     
    private:
           bool m_isMainInstance;
           QLocalSocket *identificateurClient;
     
    };
    dans fichier .cpp j'ai rajouté:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    SingleInstanceApplication::SingleInstanceApplication(const QString &localName, int &argc, char **argv) : QApplication(argc, argv), m_isMainInstance(false)
    {
        m_socket = new QLocalSocket();
        m_socket->connectToServer(localName);
        // on essaie de se connecter a un potentiel serveur local
        if(m_socket->waitForConnected(100))
        {
            // ca a fonctionné... donc il existe deja une instance de notre logiciel
            QThread::msleep(50);
            // ex: ca envoi "action_of_my_button" a l instance principale
            sendArgumentsToMainInstance(argv);
            // on ferme la connection.
            m_socket->close();
        }
        else
        {
            // ca ne fonctionne pas, donc il n y a pas encore d instance principale...
            m_isMainInstance = true;
            m_localServer = new QLocalServer(this);
            connect(m_localServer, SIGNAL(&QLocalServer::newConnection), this, SLOT(&SingleInstanceApplication::localServerHasNewConnexion()));
            m_localServer->listen(localName);
        }
     
    }
     
    void SingleInstanceApplication::localServerHasNewConnexion()
    {
        if(QLocalServer::newConnection())
        {
            //Si il y a une nouvelle connexion, on accepte la connexion sous la forme d'un QLocalSocket connecté
            //La fonction renvoie un pointeur sur un QLocalSocket qui peut être utilisé pour communiquer avec le client
            identificateurClient = new QLocalSocket();
            identificateurClient = QLocalServer::nextPendingConnection();
            connect(identificateurClient, SIGNAL(readyRead()), this, SLOT(receiveData(char)));
        }
    }
     
     
    void SingleInstanceApplication::sendArgumentsToMainInstance(char argv)
    {
        //Lorsque l'on appuit sur un bouton de l'interface web, par exemple le bouton pour allumer la LED1, cela doit
        //envoyer l'action d'appuyer sur le bouton pour allumer la LED1
        QLocalSocket::writeData(argv);
    }
     
    void SingleInstanceApplication::receiveData(char argv)
    {
        qint64 tailleMot = QLocalSocket::bytesAvailable();
        QLocalSocket::readData(argv, tailleMot);
    }
    et mon main.cpp est devenu:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    int main(int argc, char *argv[])
    {
        SingleInstanceApplication a("GrandEssai", argc, argv);
        if(a.isRunning())
        {
            return(0);
        }
     
        QApplication a(argc, argv);
        MainWindow w;
        w.show();
     
        return a.exec();
    }

  10. #10
    Membre éclairé
    Profil pro
    Inscrit en
    Février 2009
    Messages
    383
    Détails du profil
    Informations personnelles :
    Localisation : Belgique

    Informations forums :
    Inscription : Février 2009
    Messages : 383
    Points : 658
    Points
    658
    Par défaut
    * Il y a un premier soucis ici :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    connect(identificateurClient, SIGNAL(readyRead()), this, SLOT(receiveData(char)));
    Il faut virer l argument de receiveData... vu que le signal n a pas d argument.

    * Et pour le code de receiveData() (sans l argument)

    Tu peux recuperer le socket qui avait envoyé le signal par le biais de sender().
    Il te suffit de faire un qobject_cast pour avoir une instance QLocalSocket.
    Et avec cette instance tu peux faire le read.

    * comprends tu comment tester si ca fonctionne correctement ?
    Pense à mettre des qDebug() pour verifier que ca passe ou il faut...

    ps: pas la peine d envoyer des MP.

  11. #11
    Membre confirmé

    Homme Profil pro
    Étudiant
    Inscrit en
    Avril 2011
    Messages
    532
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 34
    Localisation : France, Isère (Rhône Alpes)

    Informations professionnelles :
    Activité : Étudiant
    Secteur : Enseignement

    Informations forums :
    Inscription : Avril 2011
    Messages : 532
    Points : 604
    Points
    604
    Par défaut
    Citation Envoyé par RapotOR Voir le message
    * comprends tu comment tester si ca fonctionne correctement ?
    Pense à mettre des qDebug() pour verifier que ca passe ou il faut...
    Par contre non, je ne comprend pas comment tester si ça fonction correctement parce qu'en fait, si je comprend bien le code, je crée un serveur local qui fait fonctionner mon programme de communication de l'automate. La création de ce serveur local me permet la création de socket pour établir la communication entre un client (ma futur page web) et le serveur mais je ne comprend pas comment je vais dire que ma page web est mon client et comment vérifier si cela fonctionne.

    Dans un TP de prise en main de Qt que j'ai suivi, il nous été demander de créer un serveur et un client pour faire un tchat (avec QTCPServer). Je pensait m'en inspirer en regardant le code mais la différence que j'ai pu noté (et que je ne vois pas ici) c'est que lorsque je créé mon serveur QTCPServer je récupérer l'adresse IP local de mon ordi et je précisais un port de connexion. Donc je comprenais comment comment y accéder mais là je suis perdu

    PS: désolé pour le MP mais je suis un peu en panique, j'arrive pas à avancer tout seul (et c'est pas faute d'essayer je te le jure) mais il faut que mon projet avance, c'est pour cela que je suis en panique

  12. #12
    Membre confirmé

    Homme Profil pro
    Étudiant
    Inscrit en
    Avril 2011
    Messages
    532
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 34
    Localisation : France, Isère (Rhône Alpes)

    Informations professionnelles :
    Activité : Étudiant
    Secteur : Enseignement

    Informations forums :
    Inscription : Avril 2011
    Messages : 532
    Points : 604
    Points
    604
    Par défaut
    Citation Envoyé par RapotOR Voir le message
    * Et pour le code de receiveData() (sans l argument)

    Tu peux recuperer le socket qui avait envoyé le signal par le biais de sender().
    Il te suffit de faire un qobject_cast pour avoir une instance QLocalSocket.
    Et avec cette instance tu peux faire le read.
    Donc j'ai corrigé la première erreur sur le connect en enlevant l'argument et donc en suivant tes indications pour le code de receiveData(), j'obtiens ceci:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    void SingleInstanceApplication::receiveData()
    {
        QLocalSocket *Socket = new QLocalSocket::sender();
        QLocalSocket *SocketDouVientLeSignal = qobject_cast<QLocalSocket *>(Socket);
        SocketDouVientLeSignal->readData();
    }
    Est-ce que cela paraît correct ?

  13. #13
    Membre confirmé

    Homme Profil pro
    Étudiant
    Inscrit en
    Avril 2011
    Messages
    532
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 34
    Localisation : France, Isère (Rhône Alpes)

    Informations professionnelles :
    Activité : Étudiant
    Secteur : Enseignement

    Informations forums :
    Inscription : Avril 2011
    Messages : 532
    Points : 604
    Points
    604
    Par défaut
    Et je viens de me rendre compte de quelque chose, je ne possède pas la librairie QtSingleApplication (qui je suppose doit être utile à la création de ma classe SingleInstanceApplication) donc pourrais-tu m'indiquer où la télécharger svp ???

  14. #14
    Membre éclairé
    Profil pro
    Inscrit en
    Février 2009
    Messages
    383
    Détails du profil
    Informations personnelles :
    Localisation : Belgique

    Informations forums :
    Inscription : Février 2009
    Messages : 383
    Points : 658
    Points
    658
    Par défaut
    QtSingleApplication ou SingleInstanceApplication , ca fait la meme chose! C'est juste que je n'ai pas utilisé QtSingleApplication...


    J'avais bien pensé que tu ne comprenais pas l’idée...

    La première instance est lancée par défaut sur la machine.
    Ensuite, les actions sur les boutons de ton interface web ne font que lancer d'autres instances de ton logiciel qui enverront les actions à l'instance déjà lancée.

  15. #15
    Membre confirmé

    Homme Profil pro
    Étudiant
    Inscrit en
    Avril 2011
    Messages
    532
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 34
    Localisation : France, Isère (Rhône Alpes)

    Informations professionnelles :
    Activité : Étudiant
    Secteur : Enseignement

    Informations forums :
    Inscription : Avril 2011
    Messages : 532
    Points : 604
    Points
    604
    Par défaut
    Citation Envoyé par RapotOR Voir le message
    QtSingleApplication ou SingleInstanceApplication , ca fait la meme chose! C'est juste que je n'ai pas utilisé QtSingleApplication...
    par contre on est bien d'accord sur le fait que QtSingleApplication n'est pas d'office sur Qt et qu'il faut bien télécharger la bibliothèque


    Citation Envoyé par RapotOR Voir le message
    J'avais bien pensé que tu ne comprenais pas l’idée...

    La première instance est lancée par défaut sur la machine.
    Ensuite, les actions sur les boutons de ton interface web ne font que lancer d'autres instances de ton logiciel qui enverront les actions à l'instance déjà lancée.
    Ok mais ce que j'arrive toujours pas à comprendre (je doit être un peu idiot) c'est comment mon interface web fait pour lancer d'autre instances et que si par exemple j'ai un bouton sur mon interface web qui fait allumer la LED1, comment on fait pour dire qu'il faut allumer la LED1, je comprend pas le lien entre la page web et le programme (désolé de te causé tant de problème)

  16. #16
    Membre éclairé
    Profil pro
    Inscrit en
    Février 2009
    Messages
    383
    Détails du profil
    Informations personnelles :
    Localisation : Belgique

    Informations forums :
    Inscription : Février 2009
    Messages : 383
    Points : 658
    Points
    658
    Par défaut
    L'interface web (ton bouton) lance l’exécution du coté serveur (web) du code qui lance ton programme avec la commande adéquate.

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    IF ( POST['BOUTON_ALLUME_LED1'] ) 
    exec ( "./MONPROGRAMME ALLUME_MA_LED1")
    END IF

    Donc en résumé:

    1. CLIENT WEB
      bouton formulaire POST -> l'utilisateur clique sur le bouton
    2. serveur web
      Vérifier que bouton a été actionné (POST variable)
      -> actionner le programme Qt (ex: exec) avec un argument "ACTION_LED"
    3. instance secondaire du programme Qt (pas l'instance principale)
      remarque qu'il existe une autre instance (single app)
      -> envoi "ACTION_LED" à l'instance principale
    4. l'instance principale reçoit une connexion
      -> elle lit la donnée et reçoit "ACTION_LED"... et actionne la led.

    est-ce que cela fait du sens?

  17. #17
    Membre confirmé

    Homme Profil pro
    Étudiant
    Inscrit en
    Avril 2011
    Messages
    532
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 34
    Localisation : France, Isère (Rhône Alpes)

    Informations professionnelles :
    Activité : Étudiant
    Secteur : Enseignement

    Informations forums :
    Inscription : Avril 2011
    Messages : 532
    Points : 604
    Points
    604
    Par défaut
    Citation Envoyé par RapotOR Voir le message
    L'interface web (ton bouton) lance l’exécution du coté serveur (web) du code qui lance ton programme avec la commande adéquate.

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    IF ( POST['BOUTON_ALLUME_LED1'] ) 
    exec ( "./MONPROGRAMME ALLUME_MA_LED1")
    END IF

    Donc en résumé:

    1. CLIENT WEB
      bouton formulaire POST -> l'utilisateur clique sur le bouton
    2. serveur web
      Vérifier que bouton a été actionné (POST variable)
      -> actionner le programme Qt (ex: exec) avec un argument "ACTION_LED"
    3. instance secondaire du programme Qt (pas l'instance principale)
      remarque qu'il existe une autre instance (single app)
      -> envoi "ACTION_LED" à l'instance principale
    4. l'instance principale reçoit une connexion
      -> elle lit la donnée et reçoit "ACTION_LED"... et actionne la led.

    est-ce que cela fait du sens?
    Oui, là je comprend la démarche est le lien donc si on suit tout exemple, dans mon programme Qt, pour allumer la LED1 j'ai un slot void on_pushButton_LED1_clicked() donc dans mon client avec avec le post dans le if je vais écrire:

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    IF ( POST['BOUTON_ALLUME_LED1'] ) 
    exec ( "./MONPROGRAMME on_pushButton_LED1_clicked")
    END IF
    si j'ai bien compris.

    Par contre, est-ce que tu peux me confirmer le fait qu'il faut bien rajouter la bibliohèque QtSingleApplication (ou QSingleInstanceApplication) en la téléchargeant et en l'incluant dans mon fichier .pro

  18. #18
    Membre confirmé

    Homme Profil pro
    Étudiant
    Inscrit en
    Avril 2011
    Messages
    532
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 34
    Localisation : France, Isère (Rhône Alpes)

    Informations professionnelles :
    Activité : Étudiant
    Secteur : Enseignement

    Informations forums :
    Inscription : Avril 2011
    Messages : 532
    Points : 604
    Points
    604
    Par défaut
    Par contre j'ai un problème avec mon receiveData() parce que tu m'a dit qu'il fallait enlever l'argument (entre les parenthèses de receiveData) sauf qu'il faut que je passe un quelque chose (de type char) à readData et je ne vois pas quoi mettre dedans

  19. #19
    Membre confirmé

    Homme Profil pro
    Étudiant
    Inscrit en
    Avril 2011
    Messages
    532
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 34
    Localisation : France, Isère (Rhône Alpes)

    Informations professionnelles :
    Activité : Étudiant
    Secteur : Enseignement

    Informations forums :
    Inscription : Avril 2011
    Messages : 532
    Points : 604
    Points
    604
    Par défaut
    RapotOR,

    Il y a eu un peu de changement depuis la dernière fois, en allant sur un autre forum, j'ai trouvé une personne qui à pu m'aider pour la partie création d'une instance unique de mon programme et qui si un second se lance, rien ne s'ouvre et un message avec QDebug apprait dans ma fenêtre disant "already exist".

    Voici le programme tel qu'il est actuellement, en essayant de mêler le programme où tu m'a aidé pour le serveur et les sockets et le programme que l'on m'a communiqué pour avoir une seule instance à la fois:

    SingleInstance.h:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    51
    52
    53
    54
    55
    56
    #ifndef SINGLEAPPLICATION_H
    #define SINGLEAPPLICATION_H
     
    #include <QApplication>
    #include <QSharedMemory>
    #include <QStringList>
     
    #include <QtNetwork/QTcpServer>
    #include <QtNetwork/QTcpSocket>
     
    #include "mainwindow.h"
     
    class SingleApplication : public QApplication
    {
            Q_OBJECT
    public:
            SingleApplication(int &argc, char *argv[], const QString uniqueKey);
     
            bool alreadyExists() const{
                return bAlreadyExists;
            }
            bool isMasterApp() const{
                return !alreadyExists();
            }
     
            bool sendMessage(const QString &message);
     
    public slots:
            void checkForMessage();
     
    signals:
            void messageAvailable(const QStringList& messages);
     
     
    private slots:
            void nouvelleConnexion();
            void donneesRecues();
            void deconnexionClient();
     
            void sendArgumentsToMainInstance(char **argv);
     
    private:
            bool bAlreadyExists;
            QSharedMemory sharedMemory;
     
     
            QLocalSocket *m_socket;
     
            QLocalServer *serveur;
            QList<QLocalSocket *> clients;
            quint64 tailleMessage;
     
    };
     
     
    #endif // SINGLEAPPLICATION_H
    SingleInstance.cpp:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    51
    52
    53
    54
    55
    56
    57
    58
    59
    60
    61
    62
    63
    64
    65
    66
    67
    68
    69
    70
    71
    72
    73
    74
    75
    76
    77
    78
    79
    80
    81
    82
    83
    84
    85
    86
    87
    88
    89
    90
    91
    92
    93
    94
    95
    96
    97
    98
    99
    100
    101
    102
    103
    104
    105
    106
    107
    108
    109
    110
    111
    112
    113
    114
    115
    116
    117
    118
    119
    120
    121
    122
    123
    124
    125
    126
    127
    128
    129
    130
    131
    132
    133
    134
    135
    136
    137
    138
    139
    140
    141
    142
    143
    144
    145
    146
    147
    148
    149
    150
    151
    152
    153
    154
    155
    156
    157
    158
    159
    160
    161
    162
    163
    164
    165
    166
    167
    168
    169
    170
    171
    172
    173
    174
    175
    176
    177
    178
    179
    #include <QTimer>
    #include <QByteArray>
    #include <QThread>
     
    #include "mainwindow.h"
    #include "SingleApplication.h"
     
    #include <QtNetwork/QTcpServer>
     
    SingleApplication::SingleApplication(int &argc, char *argv[], const QString uniqueKey) : QApplication(argc, argv)
    {
        sharedMemory.setKey(uniqueKey);
     
        // when can create it only if it doesn't exist
        if (sharedMemory.create(5000))
        {
            sharedMemory.lock();
            *(char*)sharedMemory.data() = '\0';
            sharedMemory.unlock();
     
            bAlreadyExists = false;
     
            // start checking for messages of other instances.
            QTimer *timer = new QTimer(this);
            connect(timer, SIGNAL(timeout()), this, SLOT(checkForMessage()));
            timer->start(200);
     
        }
        // it exits, so we can attach it?!
        else if (sharedMemory.attach()){
            bAlreadyExists = true;
        }
        else{
            // error
        }
     
     
        // Gestion du serveur
     
     
        m_socket = new QLocalSocket();
        m_socket->connectToServer((uniqueKey));
        if(m_socket->waitForConnected(100))
        {
            qDebug("ça a fonctionné, donc il existe déjà une instance de notre logiciel");
            QThread::msleep(50);
            qDebug("Ca envoi l'action de mon bouton a l'instance principale");
            sendArgumentsToMainInstance(argv);
            qDebug("Onferme la connection");
            m_socket->close();
        }
        else
        {
            qDebug("Création de l'instance principale et du serveur");
            serveur = new QLocalServer(this);
            if (!serveur->listen(uniqueKey)) // Démarrage du serveur sur toutes les IP disponibles et sur le port 50585
            {
                // Si le serveur n'a pas été démarré correctement
                qDebug("Le serveur n'a pas été démarré correctement");
            }
            else
            {
                // Si le serveur a été démarré correctement
                qDebug("le serveur a été démarré correctement");
                connect(serveur, SIGNAL(newConnection()), this, SLOT(nouvelleConnexion()));
            }
        }
     
     
    }
     
    // public slots.
     
    void SingleApplication::checkForMessage()
    {
        QStringList arguments;
     
        sharedMemory.lock();
        char *from = (char*)sharedMemory.data();
     
        while(*from != '\0'){
            int sizeToRead = int(*from);
            ++from;
     
            QByteArray byteArray = QByteArray(from, sizeToRead);
            byteArray[sizeToRead] = '\0';
            from += sizeToRead;
     
            arguments << QString::fromUtf8(byteArray.constData());
        }
     
        *(char*)sharedMemory.data() = '\0';
        sharedMemory.unlock();
     
        if(arguments.size()) emit messageAvailable( arguments );
    }
     
     
     
     
     
    void SingleApplication::nouvelleConnexion()
    {
        QLocalSocket *nouveauClient = serveur->nextPendingConnection();
        clients << nouveauClient;
     
        connect(nouveauClient, SIGNAL(readyRead()), this, SLOT(donneesRecues()));
        connect(nouveauClient, SIGNAL(disconnected()), this, SLOT(deconnexionClient()));
    }
     
     
     
    void SingleApplication::donneesRecues()
    {
        // 1 : on reçoit un paquet (ou un sous-paquet) d'un des clients
     
            // On détermine quel client envoie le message (recherche du QTcpSocket du client)
            QLocalSocket *socket = qobject_cast<QLocalSocket *>(sender());
            if (socket == 0) // Si par hasard on n'a pas trouvé le client à l'origine du signal, on arrête la méthode
                return;
     
            // Si tout va bien, on continue : on récupère le message
            QDataStream in(socket);
     
            if (tailleMessage == 0) // Si on ne connaît pas encore la taille du message, on essaie de la récupérer
            {
                if (socket->bytesAvailable() < (int)sizeof(quint16)) // On n'a pas reçu la taille du message en entier
                     return;
     
                in >> tailleMessage; // Si on a reçu la taille du message en entier, on la récupère
            }
     
            // Si on connaît la taille du message, on vérifie si on a reçu le message en entier
            if (socket->bytesAvailable() < tailleMessage) // Si on n'a pas encore tout reçu, on arrête la méthode
                return;
     
     
            // Si ces lignes s'exécutent, c'est qu'on a reçu tout le message : on peut le récupérer !
            QString message;
            in >> message;
     
            // 3 : remise de la taille du message à 0 pour permettre la réception des futurs messages
            tailleMessage = 0;
    }
     
    void SingleApplication::deconnexionClient()
    {
            // On détermine quel client se déconnecte
            QLocalSocket *socket = qobject_cast<QLocalSocket *>(sender());
            if (socket == 0) // Si par hasard on n'a pas trouvé le client à l'origine du signal, on arrête la méthode
                return;
     
            clients.removeOne(socket);
     
            socket->deleteLater();
    }
     
     
    void SingleApplication::sendArgumentsToMainInstance(char **argv)
    {
        //Lorsque l'on appuit sur un bouton de l'interface web, par exemple le bouton pour allumer la LED1, cela doit
        //envoyer l'action d'appuyer sur le bouton pour allumer la LED1
     
        QLocalSocket *socket = qobject_cast<QLocalSocket *>(sender());
        if (socket == 0) // Si par hasard on n'a pas trouvé le client à l'origine du signal, on arrête la méthode
            return;
     
        // Si tout va bien, on continue : on récupère le message
        QDataStream in(socket);
     
        if (tailleMessage == 0) // Si on ne connaît pas encore la taille du message, on essaie de la récupérer
        {
            if (socket->bytesAvailable() < (int)sizeof(quint64)) // On n'a pas reçu la taille du message en entier
                 return;
     
            in >> tailleMessage; // Si on a reçu la taille du message en entier, on la récupère
        }
        QLocalSocket::writeData(argv, tailleMessage);
    }
    J'ai encore des erreurs mais penses-tu que je suis sur la bonne voie ??? Parce que j'ai beaucoup de mal à implémenter correctement sendArgumentsToMainInstance

Discussions similaires

  1. Logiciel ou Interface Web pour la gestion d'un Active Directory
    Par the_ourson dans le forum Autres Solutions d'entreprise
    Réponses: 0
    Dernier message: 05/01/2010, 09h15
  2. Réponses: 10
    Dernier message: 03/03/2009, 11h04
  3. Interface web pour SQL Server
    Par malakoo dans le forum MS SQL Server
    Réponses: 1
    Dernier message: 13/02/2006, 11h52
  4. Interface Web pour administrer NFS, FTP et Apache2
    Par Rekiem dans le forum Serveurs (Apache, IIS,...)
    Réponses: 3
    Dernier message: 09/01/2006, 10h12
  5. [Outils]Interface WEB pour la gestion de projet ?
    Par elitost dans le forum Outils
    Réponses: 8
    Dernier message: 04/03/2005, 13h46

Partager

Partager
  • Envoyer la discussion sur Viadeo
  • Envoyer la discussion sur Twitter
  • Envoyer la discussion sur Google
  • Envoyer la discussion sur Facebook
  • Envoyer la discussion sur Digg
  • Envoyer la discussion sur Delicious
  • Envoyer la discussion sur MySpace
  • Envoyer la discussion sur Yahoo