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

Python Discussion :

Comment n'instancier qu'une seule fois un programme


Sujet :

Python

  1. #1
    Membre du Club
    Homme Profil pro
    Administrateur de base de données
    Inscrit en
    Janvier 2012
    Messages
    50
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations professionnelles :
    Activité : Administrateur de base de données
    Secteur : Bâtiment Travaux Publics

    Informations forums :
    Inscription : Janvier 2012
    Messages : 50
    Points : 45
    Points
    45
    Par défaut Comment n'instancier qu'une seule fois un programme
    Bonjour à tous

    j'ai lu l'article sur comment n’instancier qu'une seule fois un programme de la faq python (ici) et je dois dire que ce n'est pas ça ce que je cherche à faire,
    par contre non seulement je veux executer qu'une seule fois le programme, mais en plus si je clique une deuxieme fois sur l'icone du programme, alors que ce dernier est ouvert , la main bascule sur le programme.

    et merci pour toute propositions.

    os windows7
    python3.2
    Gui PyQt4

  2. #2
    Membre habitué
    Inscrit en
    Avril 2010
    Messages
    99
    Détails du profil
    Informations personnelles :
    Âge : 41

    Informations forums :
    Inscription : Avril 2010
    Messages : 99
    Points : 143
    Points
    143
    Par défaut
    Bonjour,

    cet exemple de code semble correspondre à ce que tu veux: https://gist.github.com/blaxter/5413516
    Il est destiné à Pyside mais il doit fonctionner tel quel pour PyQt.

  3. #3
    Expert éminent

    Avatar de deusyss
    Homme Profil pro
    Expert Python
    Inscrit en
    Mars 2010
    Messages
    1 659
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 41
    Localisation : France, Ille et Vilaine (Bretagne)

    Informations professionnelles :
    Activité : Expert Python
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Mars 2010
    Messages : 1 659
    Points : 8 442
    Points
    8 442
    Par défaut
    Hello,

    Sinon tu as également la lib Tendo avec Singleton. Cette lib ne sert quasiment qu'à ça.
    "La connaissance appartient à tout le monde" (Film Antitrust)

    Tout le nécessaire pour Python:
    *News/Accueil *Cours/tutoriels *FAQ
    *Forums *Outils dédiés *Mon espace personnel avec mes Articles, Cours et Tutoriels

  4. #4
    Membre averti
    Homme Profil pro
    Développeur en formation
    Inscrit en
    Juillet 2013
    Messages
    300
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations professionnelles :
    Activité : Développeur en formation
    Secteur : High Tech - Multimédia et Internet

    Informations forums :
    Inscription : Juillet 2013
    Messages : 300
    Points : 413
    Points
    413
    Par défaut
    Je verrais bien un simple fichier avec "non instancié" dedans quand le programme n'a jamais été lancé, celui-ci est modifié en "en cours d'instanciation" quand le programme est lancé et lors de la fermeture (doit être en GUI du coup, sans console de commande fermable) "instancié". Pour ce qui est de ta 2ème demande, le programme lit le fichier au début, bien sûr (pour savoir s'il doit se lancer, bon, il s'est déjà lancé mais on triche un peu), et s'il voit "en cours d'instanciation", il crée un autre fichier (vide) et se ferme.
    L'autre programme aura un thread (ou autre méthode d'exécution parallèle) qui tente en permanence de lire ce fichier - qui n'existe pas tant qu'une autre instance du programme n'est pas ouverte - utilise un truc du genre Tk.iconify() (sur tkinter) afin de remettre le programme au premier plan.

    J'avoue que cette méthode est un peu barbare mais elle marche.
    Bouddha : Tout n'est qu'illusion en ce bas monde.
    Jésus : Tout est amour divin.
    Einstein : Tout est relatif dans cet espace-temps.
    Moi : Tout est binaire sur ce forum.

  5. #5
    Expert éminent

    Avatar de deusyss
    Homme Profil pro
    Expert Python
    Inscrit en
    Mars 2010
    Messages
    1 659
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 41
    Localisation : France, Ille et Vilaine (Bretagne)

    Informations professionnelles :
    Activité : Expert Python
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Mars 2010
    Messages : 1 659
    Points : 8 442
    Points
    8 442
    Par défaut
    Oui mais elle a un gros defaut. SI ton programme crash, ton fichier reste en place, et au lancement suivant, impossible de le lancer...
    "La connaissance appartient à tout le monde" (Film Antitrust)

    Tout le nécessaire pour Python:
    *News/Accueil *Cours/tutoriels *FAQ
    *Forums *Outils dédiés *Mon espace personnel avec mes Articles, Cours et Tutoriels

  6. #6
    Expert éminent
    Avatar de tyrtamos
    Homme Profil pro
    Retraité
    Inscrit en
    Décembre 2007
    Messages
    4 462
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Var (Provence Alpes Côte d'Azur)

    Informations professionnelles :
    Activité : Retraité

    Informations forums :
    Inscription : Décembre 2007
    Messages : 4 462
    Points : 9 249
    Points
    9 249
    Billets dans le blog
    6
    Par défaut
    Bonjour,

    Avec PyQt4, j'utilise une solution avec QSharedMemory qui marche bien. En dehors de PyQt4, j'utilise une solution issue de portalocker (https://pypi.python.org/pypi/portalocker) que j'ai modifiée: http://python.jpvweb.com/mesrecettes...er_double_exec. Ceci à la suite d'une discussion sur ce forum et d'une suggestion de wiztricks (http://www.developpez.net/forums/d10...source-base64/).

    Cette solution se base non pas sur la présence ou non d'un fichier, mais sur le fait que ce fichier est ou non bloqué en écriture. De ce fait, si le 1er programme se plante, on peut le relancer parce que le plantage relâche le verrou. Ça marche sous Python 2 et 3, et c'est multiplateforme (Windows-Unix).

    Par contre, en cas de tentative d'un 2ème lancement, cela génère un message d'erreur et l'arrêt de ce 2ème lancement. Je ne sais pas donner la main automatiquement dans ce cas à l'instance en cours d'exécution: mais si quelqu'un a une solution pour ça, ça m'intéresse!
    Un expert est une personne qui a fait toutes les erreurs qui peuvent être faites, dans un domaine étroit... (Niels Bohr)
    Mes recettes python: http://www.jpvweb.com

  7. #7
    Invité
    Invité(e)
    Par défaut
    Citation Envoyé par tyrtamos Voir le message
    Bonjour,
    mais si quelqu'un a une solution pour ça, ça m'intéresse!
    Bonjour,

    Une idée comme ça en passant : en stockant le PID de l'instance en cours d'exécution dans le fichier verrou puis en appelant le PID pour qu'il repasse au premier plan lors d'un second appel ?

    Mais là, je crains que nous ne soyons plus dans Python mais plutôt dans des appels aux DLLs/SO du système lui-même donc portabilité hum hum.



    @+.

  8. #8
    Expert éminent sénior
    Homme Profil pro
    Architecte technique retraité
    Inscrit en
    Juin 2008
    Messages
    21 287
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Manche (Basse Normandie)

    Informations professionnelles :
    Activité : Architecte technique retraité
    Secteur : Industrie

    Informations forums :
    Inscription : Juin 2008
    Messages : 21 287
    Points : 36 776
    Points
    36 776
    Par défaut
    Salut,

    Citation Envoyé par tyrtamos Voir le message
    Par contre, en cas de tentative d'un 2ème lancement, cela génère un message d'erreur et l'arrêt de ce 2ème lancement. Je ne sais pas donner la main automatiquement dans ce cas à l'instance en cours d'exécution: mais si quelqu'un a une solution pour ça, ça m'intéresse!
    La solution donnée par Biribibi "fonctionne", non?
    Elle construit une classe QSingleApplication qui fait plus ou moins partie des extensions de Qt peut être pas disponibles via PyQt4.
    Après, est ce que cela répond aux besoins du PO?
    A lui de le dire...

    - W
    Architectures post-modernes.
    Python sur DVP c'est aussi des FAQs, des cours et tutoriels

  9. #9
    Invité
    Invité(e)
    Par défaut
    Citation Envoyé par wiztricks Voir le message
    Salut,
    La solution donnée par Biribibi "fonctionne", non?
    Elle construit une classe QSingleApplication qui fait plus ou moins partie des extensions de Qt peut être pas disponibles via PyQt4.
    Après, est ce que cela répond aux besoins du PO?
    A lui de le dire...

    - W
    Oui, cette solution m'a l'air très bien.

    Après, par mesure de précaution, perso je remplacerais quand même "foobar" par le nom de l'application, histoire de ne pas téléscoper d'autres applis qui auraient eu la bonne/mauvaise idée de recourir au même code générique et qui seraient en cours d'exécution au même moment que l'appli concernée.

    Un truc du genre remplacer "foobar" par self.app_name = "app_{}".format(os.path.basename(__file__)), ce serait quand même plus sûr.

    @+.

  10. #10
    Expert éminent
    Avatar de tyrtamos
    Homme Profil pro
    Retraité
    Inscrit en
    Décembre 2007
    Messages
    4 462
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Var (Provence Alpes Côte d'Azur)

    Informations professionnelles :
    Activité : Retraité

    Informations forums :
    Inscription : Décembre 2007
    Messages : 4 462
    Points : 9 249
    Points
    9 249
    Billets dans le blog
    6
    Par défaut
    Bonjour,

    Citation Envoyé par wiztricks Voir le message
    La solution donnée par Biribibi "fonctionne", non?
    Elle construit une classe QSingleApplication qui fait plus ou moins partie des extensions de Qt peut être pas disponibles via PyQt4.
    Comme la question n'a pas été posée dans le forum PyQt/PySide, je témoignais d'une solution autre.

    Mais s'il s'agit d'une solution PyQt/PySide, je préfère la mienne beaucoup plus simple. Elle consiste à créer une petite zone mémoire partagée avec QtCore.QSharedMemory(key). La clé key étant définie de façon unique pour un programme donné, Or, Qt n'accepte pas la création de 2 zones mémoire avec la même clé, ce qui est facile à tester.

    La clé peut être construite avec le nom du programme + le répertoire de l'utilisateur (ou n'importe quoi d'autre, y compris une chaine au hasard)

    Voilà un petit code démo. Avec mon exemple, la clé donne: "bd828a462d5b3af530409a5f5350b6f3cc150f65755392e6e6a55e25f6409366". Avec sha256, les collisions me semblent exclues. Mais si on veut être sûr, rien n'empêche d'encoder avec base64.

    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
    #!/usr/bin/python
    # -*- coding: utf-8 -*-
    # Python 3
     
    import sys, os
    import hashlib
    from PyQt4 import QtCore, QtGui
     
    #############################################################################
    class Fenetre(QtGui.QWidget):
     
        def __init__(self, parent=None):
            super(Fenetre, self).__init__(parent)
     
    #############################################################################
    if __name__ == '__main__':
     
        app = QtGui.QApplication(sys.argv)
     
        # Empêcher que ce programme ne soit lancé 2 fois
        chaine = "monprogramme" + os.path.expanduser('~')
        motif = hashlib.sha256()
        motif.update(chaine.encode('latin1'))
        sharedMemory = QtCore.QSharedMemory(motif.hexdigest())
        if not sharedMemory.create(50):
            QtGui.QMessageBox.critical(None, "Vérification", "Ce programme est déjà en cours d'exécution" )
            app.quit()
            sys.exit(0)
     
        # lancement de la fenêtre    
        fen = Fenetre()
        fen.show()
        sys.exit(app.exec_())
    Un expert est une personne qui a fait toutes les erreurs qui peuvent être faites, dans un domaine étroit... (Niels Bohr)
    Mes recettes python: http://www.jpvweb.com

  11. #11
    Expert éminent sénior
    Homme Profil pro
    Architecte technique retraité
    Inscrit en
    Juin 2008
    Messages
    21 287
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Manche (Basse Normandie)

    Informations professionnelles :
    Activité : Architecte technique retraité
    Secteur : Industrie

    Informations forums :
    Inscription : Juin 2008
    Messages : 21 287
    Points : 36 776
    Points
    36 776
    Par défaut
    Citation Envoyé par tyrtamos Voir le message
    Mais s'il s'agit d'une solution PyQt/PySide, je préfère la mienne beaucoup plus simple. Elle consiste à créer une petite zone mémoire partagée avec QtCore.QSharedMemory(key). La clé key étant définie de façon unique pour un programme donné, Or, Qt n'accepte pas la création de 2 zones mémoire avec la même clé, ce qui est facile à tester.
    Ok mais ou est la logique qui réveille ou remet en topmost l'instance de l'application déjà démarrée?

    - W
    Architectures post-modernes.
    Python sur DVP c'est aussi des FAQs, des cours et tutoriels

  12. #12
    Expert éminent
    Avatar de tyrtamos
    Homme Profil pro
    Retraité
    Inscrit en
    Décembre 2007
    Messages
    4 462
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Var (Provence Alpes Côte d'Azur)

    Informations professionnelles :
    Activité : Retraité

    Informations forums :
    Inscription : Décembre 2007
    Messages : 4 462
    Points : 9 249
    Points
    9 249
    Billets dans le blog
    6
    Par défaut
    Citation Envoyé par wiztricks Voir le message
    Ok mais ou est la logique qui réveille ou remet en topmost l'instance de l'application déjà démarrée?
    Malheureusement, je ne sais pas traiter cette partie.
    Un expert est une personne qui a fait toutes les erreurs qui peuvent être faites, dans un domaine étroit... (Niels Bohr)
    Mes recettes python: http://www.jpvweb.com

  13. #13
    Invité
    Invité(e)
    Par défaut
    Citation Envoyé par wiztricks Voir le message
    Ok mais ou est la logique qui réveille ou remet en topmost l'instance de l'application déjà démarrée?

    - W
    C'est vrai que de passer par un socket server permet en outre d'envoyer des requêtes à l'instance déjà en cours d'exécution e.g. passer au premier plan, accepter un nouveau document, lancer un traitement spécifique, etc.

    @+.

  14. #14
    Expert éminent sénior
    Homme Profil pro
    Architecte technique retraité
    Inscrit en
    Juin 2008
    Messages
    21 287
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Manche (Basse Normandie)

    Informations professionnelles :
    Activité : Architecte technique retraité
    Secteur : Industrie

    Informations forums :
    Inscription : Juin 2008
    Messages : 21 287
    Points : 36 776
    Points
    36 776
    Par défaut
    Citation Envoyé par tarball69 Voir le message
    C'est vrai que de passer par un socket server permet en outre d'envoyer des requêtes à l'instance déjà en cours d'exécution e.g. passer au premier plan, accepter un nouveau document, lancer un traitement spécifique, etc.
    Le PO nous dira ce qu'il pense de la solution proposée par Biribibi mais vu ce qu'il attend difficile de faire simple sans les sockets.
    nota, on peut faire avec des fichiers ou de la mémoire partagée mais c'est un peu trop compliqué pour faire juste çà.

    - W
    Architectures post-modernes.
    Python sur DVP c'est aussi des FAQs, des cours et tutoriels

Discussions similaires

  1. Réponses: 3
    Dernier message: 29/03/2010, 19h31
  2. [IDE]Comment télécharger VS2005 Express une seule fois?
    Par zamine81 dans le forum EDI/Outils
    Réponses: 2
    Dernier message: 05/01/2006, 18h14

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