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 :

Appel d'une fonction d'un module depuis un thread du script principal


Sujet :

Python

  1. #1
    Invité
    Invité(e)
    Par défaut Appel d'une fonction d'un module depuis un thread du script principal
    Bonjour,

    Dans un script principal j'explore les mises à jour d'un site internet, à chaque changement sur le site (détecté par l'un des threads) j'appelle la fonction notification() du module qui suit (pygame + win32gui.MoveWindow()) :

    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
    import pygame, time, threading, os, sys, traceback, multiprocessing
    import win32gui
    from win32api import GetSystemMetrics
    #os.environ['SDL_VIDEODRIVER'] = 'windib'
    #os.environ['SDL_VIDEO_CENTERED'] = '1'
     
    chemin = os.path.expanduser('~\Notif')
    sc_size = (500, 150)
    start_pos = (GetSystemMetrics(0),GetSystemMetrics(1))
    x,y = start_pos
    final_pos = (GetSystemMetrics(0)-510,GetSystemMetrics(1)-215)
    #os.environ['SDL_VIDEO_WINDOW_POS'] = '%i,%i' % start_pos
    #os.environ['SDL_VIDEO_CENTERED'] = '0'
     
    pygame.init()
     
    pygame.display.set_caption('Notif')
     
    bg_color =  57, 59, 61
    logo = pygame.image.load(chemin+"\\icone.png")
     
     
    default_font = pygame.font.get_default_font()
    font1 = pygame.font.SysFont("gabriola", 25, False)
    font2 = pygame.font.SysFont("arial", 19, True)
    font3 = pygame.font.SysFont("agency fb", 20, False)
     
    #Création de la fenêtre
    screen = pygame.display.set_mode(sc_size, pygame.NOFRAME)
     
    def windowEnumerationHandler(hwnd, top_windows):
        top_windows.append((hwnd, win32gui.GetWindowText(hwnd)))
     
    def get_hwnd():
        top_windows = []
        win32gui.EnumWindows(windowEnumerationHandler, top_windows)
        for i in top_windows:        
            if 'Notif' in i[1] :
                #print(i[0],i[1])
                return i[0]
     
    hwnd = get_hwnd()
    win32gui.MoveWindow(hwnd , x, y, sc_size[0], sc_size[1], True)
    clock = pygame.time.Clock()
     
    def notification(Title='Notification', Subtitle=None, Message1=None, Message2=None, Icone=False, Lien=False):
        title = font1.render(Title, True, (225, 225, 225))
        subtitle = font2.render(Subtitle, True, (255, 255, 255))
        message1 = font3.render(Message1, True, (200, 200, 200))
        message2 = font3.render(Message2, True, (200, 200, 200))
     
        end_time = False    
        done = False
        end_time = False
        retract = False
        icone = Icone
        lien = Lien
     
        while 1:
            screen.fill(bg_color)
     
            screen.blit(logo, (10,5))
            screen.blit(title,(50,9))
            screen.blit(subtitle,(5,40))
            if not icone:            
                screen.blit(message1,(5,70))
                screen.blit(message2,(5,95))
            else:
                img = pygame.image.load(icone)
                screen.blit(img,(5,70))
                screen.blit(message1,(75,70))
                screen.blit(message2,(75,95))
            if not done:
                done = True
                #hwnd = get_hwnd()
                x, y = start_pos
                while x != final_pos[0]:
                    x -= 1
                    win32gui.MoveWindow(hwnd, x, y, sc_size[0], sc_size[1], True)
                    if y > final_pos[1]:
                        y -= 1
                    #pygame.display.update()
     
            if not end_time:
                end_time = time.time()+5
     
            if time.time() > end_time and not retract:
                retract = True
                while win32gui.GetWindowRect(hwnd)[0] != start_pos[0]:            
                    win32gui.MoveWindow(hwnd, win32gui.GetWindowRect(hwnd)[0]+1, y, sc_size[0], sc_size[1], True)
                win32gui.MoveWindow(hwnd, start_pos[0], start_pos[1], sc_size[0], sc_size[1], True)
                break
            pygame.display.flip()
            clock.tick(60)
     
    def exit():
        # Be IDLE friendly
        pygame.quit()
    Si je lance le module tout seul et que je fais 15 fois de suite :
    multiprocessing.Process(target = notification, kwargs ={'Title':'tutu', 'Subtitle':'toto', 'Message1':'tata', 'Message2':'titi', 'Icone':chemin+'\\new_art.png', 'Lien':False}).start()Ca fonctionne impec !
    Le fenêtre de notification glisse de façon fluide et disparaît comme il faut.

    Par contre si j'utilise ce code dans le thread de mon script principal là c'est la cata ! (Boucle infinie de créations de processus)
    Si j'appelle la fonction avec un thread threading.Thread(target=notification, args=('tutu',...,).start() ou comme ça notification(Title = ...) ça ne marche qu'une fois ou deux voire pas du tout puis la fenêtre de notification freeze et plante.

    Je me doute que j'ai loupé un truc basique avec le multiprocessing / multithreading et pygame... Si vous pouvez m'aider à comprendre, je vous en serai reconnaissant !

  2. #2
    Expert éminent sénior
    Homme Profil pro
    Architecte technique retraité
    Inscrit en
    Juin 2008
    Messages
    21 428
    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 428
    Points : 37 010
    Points
    37 010
    Par défaut
    Salut,

    Citation Envoyé par LeNarvalo Voir le message
    Je me doute que j'ai loupé un truc basique avec le multiprocessing / multithreading et pygame... Si vous pouvez m'aider à comprendre, je vous en serai reconnaissant !
    Il faut déjà ouvrir la documentation sur le multiprocessing pour voir les spécificités de Windows... et s'assurer que le code les respecte.
    Après, il faut aussi chercher un peu sur Internet.

    - W

  3. #3
    Invité
    Invité(e)
    Par défaut
    Merci !

    J'ai essayé plusieurs choses à partir de la doc et j'arrête là les frais pour ce soir !

    Quand j'utilise :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    mp.set_start_method('fork')
    J'ai un message d'erreur.
    Quand j'utilise :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    mp.set_start_method('spawn')
    Ca tourne en boucle.

    J'ai essayé en passant par pyinstaller, pas mieux. (Apparemment seul 'fork' marche après avoir utilisé pyinstaller et je vais l'utiliser)

    J'ai essayé Lock() et là j'ai eu le droit à l'écran bleu.

    J'essayerais demain wait().

    C'est nul Windows !

  4. #4
    Expert éminent sénior
    Homme Profil pro
    Architecte technique retraité
    Inscrit en
    Juin 2008
    Messages
    21 428
    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 428
    Points : 37 010
    Points
    37 010
    Par défaut
    Salut,

    Windows ne supporte que le mode "spawn". Et je ne vois pas trop ce que pyinstaller vient faire ici. Désolé.

    - W

  5. #5
    Invité
    Invité(e)
    Par défaut
    Citation Envoyé par wiztricks Voir le message
    Salut,

    Windows ne supporte que le mode "spawn". Et je ne vois pas trop ce que pyinstaller vient faire ici. Désolé.

    - W

    Avertissement :

    Les méthodes de démarrage ’spawn’ et ’forkserver’ ne peuvent pas être utilisées avec des exécutables « figés » (c'est-à-dire des binaires produits par des paquets comme PyInstaller et cx_Freeze) sur Unix. La méthode de démarrage ’fork’ fonctionne.
    Tu peux me traduire ça en français ?
    Je vais utiliser PyInstaller pour créer un exécutable pour windows à partir de mon script. J'avais donc compris que je devais utilisé 'fork'.

    Bref c'est bientôt l'heure de la bière, les zamis !!!
    Python attendra un peu.

  6. #6
    Expert éminent sénior
    Homme Profil pro
    Architecte technique retraité
    Inscrit en
    Juin 2008
    Messages
    21 428
    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 428
    Points : 37 010
    Points
    37 010
    Par défaut
    Citation Envoyé par LeNarvalo Voir le message
    Tu peux me traduire ça en français ?
    C'est déjà écrit en français. Des tas d'explications seraient à votre portée en cherchant un peu sur Internet.

    Et vous n'avez toujours pas raconté ce que vient faire pyinstaller dans le problème décrit initialement.

    - W

  7. #7
    Membre expérimenté
    Avatar de MPython Alaplancha
    Homme Profil pro
    Paysan à 3 francs six sous
    Inscrit en
    Juin 2018
    Messages
    904
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Pyrénées Orientales (Languedoc Roussillon)

    Informations professionnelles :
    Activité : Paysan à 3 francs six sous
    Secteur : Agroalimentaire - Agriculture

    Informations forums :
    Inscription : Juin 2018
    Messages : 904
    Points : 1 591
    Points
    1 591
    Billets dans le blog
    6
    Par défaut
    Bonjour,
    @LeNarvalo:
    L'avertissement ne concerne que les systèmes Unix...

  8. #8
    Invité
    Invité(e)
    Par défaut
    @Hominidé
    Ok donc pas windows je suppose !?

    "La quasi-totalité des systèmes d'exploitations PC ou mobile (à l'exception des Windows NT) est basée sur le noyau de Unix"

    Désolé à part Python et un chouïa de batch je ne connais et ne retiens pas grand chose à l'informatique.

    Je vais refaire des tests quand mon cerveau sera rebranché !

  9. #9
    Expert éminent sénior
    Homme Profil pro
    Architecte technique retraité
    Inscrit en
    Juin 2008
    Messages
    21 428
    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 428
    Points : 37 010
    Points
    37 010
    Par défaut
    Citation Envoyé par Hominidé Voir le message
    L'avertissement ne concerne que les systèmes Unix...
    Oui enfin, çà dit juste que le démarrage "spawn" ne peut pas être utilisé avec des exécutables "freezés".
    Comme Windows ne supporte pas "fork", çà dit juste que çà marche sur UN*X modulo "fork" (sur des exécutables "freezés").

    Mais il faut aller lire un peu plus loin pour voir comment faire pour Windows... (ce qui est la joie de la lecture attentive d'une "documentation technique" où il faut tout lire, tester,... voir ce qu'il se raconte sur Internet avant de conclure quoi que ce soit).

    - W

Discussions similaires

  1. Appel d'une fonction stockée MySQL depuis un module VB.Net
    Par mddkkr dans le forum SQL Procédural
    Réponses: 0
    Dernier message: 22/09/2013, 18h12
  2. Appel d'une fonction java (dans une applet) depuis javascript
    Par foued_scorpion dans le forum Applets
    Réponses: 2
    Dernier message: 17/01/2007, 11h40
  3. [Compilation] Appel d'une fonction C++ depuis du code C
    Par bladerunners dans le forum C++
    Réponses: 1
    Dernier message: 06/09/2006, 15h26
  4. [VB6] Appel d'une fonction dans un module d'une dll
    Par speedster dans le forum VB 6 et antérieur
    Réponses: 4
    Dernier message: 05/06/2006, 18h37

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