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 :

Débutant en Python : comment surveiller un répertoire pour déclencher une action


Sujet :

Python

  1. #21
    Expert éminent
    Homme Profil pro
    Architecte technique retraité
    Inscrit en
    Juin 2008
    Messages
    21 790
    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 790
    Par défaut
    Salut,

    Citation Envoyé par Vincent-vr Voir le message
    Bon, me revoilà déjà avec un léger soucis : comment je fais pour que pendant l'exécution de la boucle de "scrutation" le programme me rende la main ?
    Il serait préférable de créer une nouvelle discussion et de montrer un peu ce que vous avez fait car la boucle de "scrutation" de votre programme, sans voir à quoi ça ressemble...

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

  2. #22
    Membre averti
    Homme Profil pro
    ex-informaticien photographe
    Inscrit en
    Septembre 2021
    Messages
    37
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 52
    Localisation : France, Cher (Centre)

    Informations professionnelles :
    Activité : ex-informaticien photographe
    Secteur : Communication - Médias

    Informations forums :
    Inscription : Septembre 2021
    Messages : 37
    Par défaut
    C'est bien simple, j'ai utilisé une boucle while infinie avec un sleep pour lister le contenu du répertoire périodiquement.
    Évidemment dès que la boucle tourne je ne peux plus agir sur l'interface...
    Bref, je cherche comment surveiller ce qui se passe niveau clic de bouton et autres manips clavier et souris.

  3. #23
    Expert éminent
    Homme Profil pro
    Architecte technique retraité
    Inscrit en
    Juin 2008
    Messages
    21 790
    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 790
    Par défaut
    Citation Envoyé par Vincent-vr Voir le message
    C'est bien simple, j'ai utilisé une boucle while infinie avec un sleep pour lister le contenu du répertoire périodiquement.
    Évidemment dès que la boucle tourne je ne peux plus agir sur l'interface...
    Bref, je cherche comment surveiller ce qui se passe niveau clic de bouton et autres manips clavier et souris.
    Dommage d'utiliser une boucle while infinie alors qu'on peut le faire sans (avec les différentes bibliothèques mentionnées)... mais pour que ça marche sans bloquer l'interface vous avez la possibilité de la pousser dans un thread séparé.

    Vous pouvez aussi revoir la séquence: on sélectionne un élève, ça attend que la photo arrive dans le répertoire en remplaçant le while infini par une fonction lancée par le GUI qui regarde le contenu du répertoire et se re-soumet elle même tant qu'il est vide.

    A vous de choisir ce qui vous convient le mieux (et ouvrez un tuto. pour apprendre les bases de la programmation de votre GUI car ils sont là pour expliquer comment faire).

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

  4. #24
    Invité
    Invité(e)
    Par défaut
    Comme dis par Wiz, le threading te permettra de faire ce que tu demandes !
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    import threading, time
    def test():
        while 1:
            print('Bye\n')
            time.sleep(1)
     
    threading.Thread(target=test,daemon=True).start()
    while 1:
        print('Hello\n')
        time.sleep(1)

  5. #25
    Membre averti
    Homme Profil pro
    ex-informaticien photographe
    Inscrit en
    Septembre 2021
    Messages
    37
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 52
    Localisation : France, Cher (Centre)

    Informations professionnelles :
    Activité : ex-informaticien photographe
    Secteur : Communication - Médias

    Informations forums :
    Inscription : Septembre 2021
    Messages : 37
    Par défaut
    Je vais essayer ça.
    J'avais essayé d'utiliser after, mais ça me renvoie une erreur que je ne comprends pas : free variable 'before' referenced before assignment in enclosing scop.

    J'appelle la première fonction avec l'appui sur le bouton de démarrage de la surveillance :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    def surveiller_rep():
        before = dict ((f, None) for f in os.listdir (RepertoireASurv))
        Photoscol.after(1000,surveiller_rep_boucle)
     
    def surveiller_rep_boucle():
        after = dict ((f, None) for f in os.listdir (RepertoireASurv))
        added = [f for f in after if not f in before]
        removed = [f for f in before if not f in after]
        if added: print("Added: ", ", ".join (added))
        before = after
        Photoscol.after(1000,surveiller_rep_boucle)
    C'est la ligne added = [f for f in after if not f in before] qui ne lui plait pas apparemment...

  6. #26
    Membre averti
    Homme Profil pro
    ex-informaticien photographe
    Inscrit en
    Septembre 2021
    Messages
    37
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 52
    Localisation : France, Cher (Centre)

    Informations professionnelles :
    Activité : ex-informaticien photographe
    Secteur : Communication - Médias

    Informations forums :
    Inscription : Septembre 2021
    Messages : 37
    Par défaut
    Je viens de comprendre : il faut redéclarer les variables after et before en global dans les fonctions ?!
    Problème, au bout d'un moment ca plante avec cette erreur : maximum recursion depth exceeded while pickling an object...

  7. #27
    Expert éminent
    Homme Profil pro
    Architecte technique retraité
    Inscrit en
    Juin 2008
    Messages
    21 790
    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 790
    Par défaut
    Citation Envoyé par Vincent-vr Voir le message
    Problème, au bout d'un moment ca plante avec cette erreur : maximum recursion depth exceeded while pickling an object...
    "pickler" des objets, c'est quelque chose que fait "automatiquement" le multiprocessing et il n'y en a pas de trace dans le code posté.

    Après, je ne comprends pas pourquoi vous comparez le contenu du répertoire avant/après plutôt que de le dédier à l'arrivée d'une image qu'on déplace après avoir été traitée. Le code serait plus simple et les éventuels point de reprise aussi.

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

  8. #28
    Membre averti
    Homme Profil pro
    ex-informaticien photographe
    Inscrit en
    Septembre 2021
    Messages
    37
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 52
    Localisation : France, Cher (Centre)

    Informations professionnelles :
    Activité : ex-informaticien photographe
    Secteur : Communication - Médias

    Informations forums :
    Inscription : Septembre 2021
    Messages : 37
    Par défaut
    J'ignore totalement comment détecter l'arrivée d'un fichier, sinon en comparant le contenu du répertoire entre un instant T et un instant T+1...

  9. #29
    Expert éminent
    Homme Profil pro
    Architecte technique retraité
    Inscrit en
    Juin 2008
    Messages
    21 790
    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 790
    Par défaut
    Citation Envoyé par Vincent-vr Voir le message
    J'ignore totalement comment détecter l'arrivée d'un fichier, sinon en comparant le contenu du répertoire entre un instant T et un instant T+1...
    Si le répertoire est toujours vide sauf lorsqu'il y a une image à traiter, on fera toujours la différence côté contenu (rien vs quelque chose que le traitement supprime).
    Mais plus besoin de se trimbaler la liste des fichiers existants d'une itération à l'autre (cette liste étant vide...)

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

  10. #30
    Membre averti
    Homme Profil pro
    ex-informaticien photographe
    Inscrit en
    Septembre 2021
    Messages
    37
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 52
    Localisation : France, Cher (Centre)

    Informations professionnelles :
    Activité : ex-informaticien photographe
    Secteur : Communication - Médias

    Informations forums :
    Inscription : Septembre 2021
    Messages : 37
    Par défaut
    Je ne veux pax déplacer les fichiers, simplement les renommer sur place.
    Le répertoire est créé lorsque je lance la session de prise de vue depuis le logiciel photo. Ce dernier n'est pas capable de m'afficher en simultané 2 répertoires d'images différents et ce ne serait pas pratique de toute façon.
    Je veux "simplement" choisir ce répertoire dans mon appli avant de lancer la surveillance en appuyant sur un bouton.
    Arrêt de la surveillance et du renommage quand je veux par appui d'un autre bouton.

  11. #31
    Expert éminent
    Homme Profil pro
    Architecte technique retraité
    Inscrit en
    Juin 2008
    Messages
    21 790
    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 790
    Par défaut
    Citation Envoyé par Vincent-vr Voir le message
    Je ne veux pax déplacer les fichiers, simplement les renommer sur place.
    Les renommer sur place ou les renommer ailleurs, c'est un peu la même chose - tant que çà reste sur le même disque physique et que les images arrivent dans un répertoire connu...

    L'avantage est que vous n'avez pas à trier un gros tas par nom ou date de création (que ce soit en le faisant vous même ou en le faisant faire par le système): il y a ou pas des fichiers à traiter.

    En plus on a une indication, lorsqu'on démarre l'application, que quelque chose s'est mal passé si on y trouve quelque chose (puisqu'il devrait être vide). Et éventuellement la possibilité de traiter intelligemment les collisions de nommage.

    Cerises sur le gâteau, moins de code: c'est moins de cas de figures à identifier côté plan de tests et de tests à faire.

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

  12. #32
    Membre averti
    Homme Profil pro
    ex-informaticien photographe
    Inscrit en
    Septembre 2021
    Messages
    37
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 52
    Localisation : France, Cher (Centre)

    Informations professionnelles :
    Activité : ex-informaticien photographe
    Secteur : Communication - Médias

    Informations forums :
    Inscription : Septembre 2021
    Messages : 37
    Par défaut
    Je ne peux pas les déplacer, sinon le logiciel photo ne les verra plus et je ne pourrai pas les visualiser en live. C'est le but premier de la prise de vue connectée : contrôler rapidement sur un grand écran ce qu'on fait

  13. #33
    Expert confirmé
    Avatar de jurassic pork
    Homme Profil pro
    Bidouilleur
    Inscrit en
    Décembre 2008
    Messages
    4 328
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations professionnelles :
    Activité : Bidouilleur
    Secteur : Industrie

    Informations forums :
    Inscription : Décembre 2008
    Messages : 4 328
    Par défaut
    hello,
    plutôt que de faire une boucle pour balayer le répertoire pour voir si quelque chose est arrivé il serait plus judicieux d'utiliser les événements. Pour faire ceci sous windows utiliser FindFirstChangeNotification (message #6 de LeNarvalo) . En utilisant PyQt comme GUI il y a une classe qui fait cela QFileSystemWatcher (exemple ici). Pour éviter une boucle on peut aussi utiliser un timer.

    Ami calmant, J.P

  14. #34
    Membre averti
    Homme Profil pro
    ex-informaticien photographe
    Inscrit en
    Septembre 2021
    Messages
    37
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 52
    Localisation : France, Cher (Centre)

    Informations professionnelles :
    Activité : ex-informaticien photographe
    Secteur : Communication - Médias

    Informations forums :
    Inscription : Septembre 2021
    Messages : 37
    Par défaut
    Il y a quand même une boucle infinie qui bloque le GUI...

  15. #35
    Membre prolifique
    Avatar de Sve@r
    Homme Profil pro
    Ingénieur développement logiciels
    Inscrit en
    Février 2006
    Messages
    12 875
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Oise (Picardie)

    Informations professionnelles :
    Activité : Ingénieur développement logiciels
    Secteur : Aéronautique - Marine - Espace - Armement

    Informations forums :
    Inscription : Février 2006
    Messages : 12 875
    Billets dans le blog
    1
    Par défaut
    Citation Envoyé par Vincent-vr Voir le message
    J'aurais bien aimé faire un bouton "arrêt de surveillance du répertoire", histoire de pouvoir changer le dit répertoire entre 2 classes par exemple... Voire même "en live" et toc il change sa surveillance !
    Et voilà. On pense être arrivé au bout et on se rend compte qu'on pourrait faire mieux. Et on peut toujours faire mieux...
    Déjà qui dit "bouton" dit "ihm". Ca c'est incontournable donc tu ne pourras pas le contourner.
    L'avantage de l'IHM c'est qu'elle gère l'évènementiel (elle détecte toute seule l'action sur ses widgets) et toi tu n'as qu'à programmer le "quoi faire quand telle action". Python possède une ihm minimaliste Tkinter donc tu peux t'y lancer. Et ensuite si ça t'intéresse alors PyQt (que j'ai déjà citée et que jurassic pork mentionne aussi) et qui fait partie des musts dans ce domaine.

    Citation Envoyé par Vincent-vr Voir le message
    J'ignore totalement comment détecter l'arrivée d'un fichier, sinon en comparant le contenu du répertoire entre un instant T et un instant T+1...
    Un dossier étant avant-tout un fichier, il possède tous les attributs d'un fichier. Notamment un "état" qui est récupérable par os.stat() et qui te donne plein d'infos dont sa taille, la date de dernière modif etc. Si par exemple cette date de dernière modif change entre T et T+1 peut-être que c'est un signe...
    Mon Tutoriel sur la programmation «Python»
    Mon Tutoriel sur la programmation «Shell»
    Sinon il y en a pleins d'autres. N'oubliez pas non plus les différentes faq disponibles sur ce site
    Et on poste ses codes entre balises [code] et [/code]

  16. #36
    Membre averti
    Homme Profil pro
    ex-informaticien photographe
    Inscrit en
    Septembre 2021
    Messages
    37
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 52
    Localisation : France, Cher (Centre)

    Informations professionnelles :
    Activité : ex-informaticien photographe
    Secteur : Communication - Médias

    Informations forums :
    Inscription : Septembre 2021
    Messages : 37
    Par défaut
    Je tourne en rond : j'ai fait une IHM avec Tkinter.
    Le problème est simplement que si je veux que l'appui sur un bouton lance un scan périodique d'un répertoire, une boucle avec un sleep fige l'IHM...
    Donc en clair : comment faire tourner périodiquement os.stat() que tu cites tout en pouvant toujours agir sur l'IHM pour lui dire simplement "arrêtes de pédaler, je vais changer de répertoire" ?
    Parce qu'en parallèle je charge dans une liste le fichier des élèves de la classe en cours de prise de vue et le but est de renommer les fichiers qui arrivent avec le nom sélectionné dans la liste.

    J'ai trouvé sur le net une bout de code qui fait ce que je veux avec un thread, mais je n'y comprends rien

    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
    from threading import Thread
    from time import sleep
    from tkinter import Button, Label, Tk
     
    i=1 
     
    class App(Tk):
     
        def __init__(self):
            Tk.__init__(self)
            self.label = Label(self, text="Stopped.")
            self.label.pack()
            self.play_button = Button(self, text="Play", command=self.play)
            self.play_button.pack(side="left", padx=2, pady=2)
            self.stop_button = Button(self, text="Stop", command=self.stop)
            self.stop_button.pack(side="left", padx=2, pady=2)
            self._thread, self._pause, self._stop = None, False, True
            i=1
     
        def action(self):
            global i
            while 1:
                i=i+1
                if self._stop:
                    break
                while self._pause:
                    self.label["text"] = "Pause... (count: {})".format(i)
                    sleep(0.1)
                self.label["text"] = "Playing... (count: {})".format(i)
                sleep(0.1)
            self.label["text"] = "Stopped."
     
        def play(self):
            if self._thread is None:
                self._stop = False
                self._thread = Thread(target=self.action)
                self._thread.start()
            self._pause = False
            self.play_button.configure(text="Pause", command=self.pause)
     
        def pause(self):
            self._pause = True
            self.play_button.configure(text="Play", command=self.play)
     
        def stop(self):
            if self._thread is not None:
                self._thread, self._pause, self._stop = None, False, True
            self.play_button.configure(text="Play", command=self.play)
     
     
    App().mainloop()

  17. #37
    Membre prolifique
    Avatar de Sve@r
    Homme Profil pro
    Ingénieur développement logiciels
    Inscrit en
    Février 2006
    Messages
    12 875
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Oise (Picardie)

    Informations professionnelles :
    Activité : Ingénieur développement logiciels
    Secteur : Aéronautique - Marine - Espace - Armement

    Informations forums :
    Inscription : Février 2006
    Messages : 12 875
    Billets dans le blog
    1
    Par défaut
    En fait, quand on code GUI il faut totalement tout repenser. Car la GUI c'est la boucle infinie. Et cette boucle réagit selon ce que l'utilisateur fait dans la GUI (il clique dans un menu, il rentre un texte dans un champ de saisie, il coche/décoche une case) etc. Bien évidemment il ne faut alors pas lancer sa propre boucle infinie dans la GUI sinon la GUI ne reprend plus la main.

    Bon je connais pas assez Tkinter vu que je suis parti direct dans Qt mais justement Qt possède un objet "QTimer" qui peut lancer une action à intervalles périodiques. A mon avis Tkinter devrait avoir un truc analogue.
    Mon Tutoriel sur la programmation «Python»
    Mon Tutoriel sur la programmation «Shell»
    Sinon il y en a pleins d'autres. N'oubliez pas non plus les différentes faq disponibles sur ce site
    Et on poste ses codes entre balises [code] et [/code]

  18. #38
    Invité
    Invité(e)
    Par défaut
    Petite question en lien avec la demande du PO :
    Pourquoi j'ai ce résultat ave ce bout de code :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    new_path_contents = dict((f,os.stat(f).st_mtime) for f in os.listdir(path_to_watch)
    for f in new_path_contents:
                        if "ZZ" in f or "1.png" in f:
                            print(f, new_path_contents[f])
                            print(os.stat(f))
    Resultat :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    ZZZZ.png 1631015804.9225547
    os.stat_result(st_mode=33206, st_ino=56576470318895521, st_dev=136258105, st_nlink=1, st_uid=0, st_gid=0, st_size=7175849, st_atime=1631015804, st_mtime=1629055024, st_ctime=1631015804)
    C'est fou, ça, non ?
    Je lui demande son st_mtime il me renvoit son st_atime.

  19. #39
    Membre averti
    Homme Profil pro
    ex-informaticien photographe
    Inscrit en
    Septembre 2021
    Messages
    37
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 52
    Localisation : France, Cher (Centre)

    Informations professionnelles :
    Activité : ex-informaticien photographe
    Secteur : Communication - Médias

    Informations forums :
    Inscription : Septembre 2021
    Messages : 37
    Par défaut
    Ce doit la méthode After, mais le pb que je rencontre alors c'est l'appel en boucle de la variable stockant la liste des fichiers...

  20. #40
    Expert confirmé
    Avatar de jurassic pork
    Homme Profil pro
    Bidouilleur
    Inscrit en
    Décembre 2008
    Messages
    4 328
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations professionnelles :
    Activité : Bidouilleur
    Secteur : Industrie

    Informations forums :
    Inscription : Décembre 2008
    Messages : 4 328
    Par défaut
    avec tkinter il y a moyen d'utiliser des événements personnalisés et avec le module python watchdog on peut surveiller des répertoires. Voir exemple ici

    voici ce que donne ce code par exemple :
    Nom : tkWatchdog.PNG
Affichages : 148
Taille : 57,5 Ko

Discussions similaires

  1. Réponses: 5
    Dernier message: 10/08/2011, 11h16
  2. comment surveiller un répertoire à distance?
    Par rainy_kll dans le forum Développement de jobs
    Réponses: 2
    Dernier message: 08/07/2010, 18h04
  3. Réponses: 2
    Dernier message: 31/12/2008, 12h16
  4. Réponses: 7
    Dernier message: 21/10/2004, 09h13
  5. [PowerAMC] Comment s'en servir pour creer une base?
    Par Elmilouse dans le forum Access
    Réponses: 2
    Dernier message: 27/07/2004, 09h53

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