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

GUI Python Discussion :

PyQt QSystemTrayIcon problème d'affichage menu


Sujet :

GUI Python

  1. #1
    Membre à l'essai
    Homme Profil pro
    Electronicien
    Inscrit en
    Août 2014
    Messages
    16
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 36
    Localisation : Belgique

    Informations professionnelles :
    Activité : Electronicien
    Secteur : Aéronautique - Marine - Espace - Armement

    Informations forums :
    Inscription : Août 2014
    Messages : 16
    Points : 11
    Points
    11
    Par défaut PyQt QSystemTrayIcon problème d'affichage menu
    Bonsoir,

    Après de longues recherches je capitule encore une fois..

    Je cherche simplement à remplacer l'icone de mon SysTray pendant la marche de mon programme. (Icone état de marche/Etat d'arrêt)

    Le problème est que quand je fais Hide(), Show() le menu de mon SysTray ne fonctionne plus..

    Le but ultime de cette manœuvre est que lorsque l'utilisateur entre la combinaison de touche CTRL + NUMPAD0,

    le programme change son état de marche et donc change son icone SysTray.



    Voici une partie du code:

    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
    #!/usr/bin/python
     
    from threading import Thread
    from PyQt5.QtCore import *
    from PyQt5.QtWidgets import *
    from PyQt5.QtGui import *
    import os, sys, time, ctypes, win32con
    from ctypes import wintypes
     
    fenetre = None
    trayIcon = None
    statut_on_off = True
     
     
    class MaFenetre(QWidget):
     
         def __init__(self, FL=220, FH=100):
            QWidget.__init__(self) 
     
            self.setWindowIcon(QIcon("icone64.ico"))
            self.setWindowTitle("Window")
            self.setFixedSize(FL, FH)
     
         def closeEvent(self, event): 
            global trayIcon
            event.ignore()
            self.hide()       
     
     
     
     
    class SystemTrayIcon(QSystemTrayIcon):
     
        def __init__(self, icon, parent=None):
            QSystemTrayIcon.__init__(self, icon, parent)
            self.menu = QMenu(parent)
            self.exitAction = self.menu.addAction("Exit")
            self.MenuPrincipal = self.menu.addAction("Menu principal")
            self.exitAction.triggered.connect(SystemTrayIcon.EXIT)
            self.MenuPrincipal.triggered.connect(SystemTrayIcon.MenuPrincipal)
            self.setContextMenu(self.menu)
     
        def EXIT():
            QApplication.quit()
     
        def MenuPrincipal(self,):
            global trayIcon
            global fenetre
            fenetre.show()
     
        def on_off(self,):
            global statut_on_off
            global trayIcon
     
            if statut_on_off == True:
                statut_on_off = False
                trayIcon.hide()
            else:
                statut_on_off = True
                trayIcon.show()
            return
     
     
    def HotKeysS():
     
      byref = ctypes.byref
      user32 = ctypes.windll.user32   
     
      def NUMPAD0():
        SystemTrayIcon.on_off(trayIcon)  
     
     
      HOTKEYS = {
        0 : (win32con.VK_NUMPAD0, win32con.MOD_CONTROL),
      }
     
     
      HOTKEY_ACTIONS = {
        0 : NUMPAD0,
      }
     
      for id, (vk, modifiers) in HOTKEYS.items():
        print ("Registering id", id, "for key", vk)
        if not user32.RegisterHotKey (None, id, modifiers, vk):
          print ("Unable to register id", id)
     
     
      try:
        msg = wintypes.MSG ()
        while user32.GetMessageA (byref (msg), None, 0, 0) != 0:
          if msg.message == win32con.WM_HOTKEY:
            action_to_take = HOTKEY_ACTIONS.get (msg.wParam)
            if action_to_take:
              action_to_take ()
          user32.TranslateMessage (byref (msg))
          user32.DispatchMessageA (byref (msg))
      finally:
        for id in HOTKEYS.keys ():
          user32.UnregisterHotKey (None, id)
     
     
     
    def main():
        global trayIcon
        global fenetre  
        a=QApplication(sys.argv)
        TI=QWidget()
        trayIcon = SystemTrayIcon(QIcon("icone64.ico"), TI)
        fenetre=MaFenetre()
        trayIcon.show()
        sys.exit(a.exec_())
     
    thread_1 = Thread(target = HotKeysS)
     
    if __name__ == '__main__':
        thread_1.start()
        main()
    Avant de pousser sur CTRL+NUMPAD0
    Nom : Systray1.png
Affichages : 341
Taille : 127,1 Ko

    Après..
    Nom : Systray2.png
Affichages : 290
Taille : 67,2 Ko


    Voilà si quelqu'un a l'explication je lui en serais super reconnaissant !

    Merci d'avance,

    Bonne journée
    Gauthier

  2. #2
    Expert éminent
    Avatar de tyrtamos
    Homme Profil pro
    Retraité
    Inscrit en
    Décembre 2007
    Messages
    4 461
    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 461
    Points : 9 248
    Points
    9 248
    Billets dans le blog
    6
    Par défaut
    Bonjour,

    Juste une idée: si PyQt5 n'est pas plus "thread safe" que PyQt4, il vaudrait mieux ne pas appeler directement une fonction Qt dans le thread (SystemTrayIcon.on_off(trayIcon)).

    J'utilise couramment QSystemTrayIcon de PyQt4 (y compris après traitement par cx_freeze), mais ça marche sans thread. Voir mon tuto ici: http://python.jpvweb.com/mesrecettes...t4_system_tray.

    Par contre, je n'ai pas (encore) de hotkey (et ce dernier point m'intéresse).

    [Edit] voilà un code simplifié sur le sujet sans thread ni hotkey mais sous PyQt4 (et Python 3.4). Je ne sais pas si c'est facile de le convertir en PyQt5.

    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
    #! /usr/bin/python
    # -*- coding: utf-8 -*-
    # Python 3, PyQt4
     
    import os, sys
     
    from PyQt4 import QtCore, QtGui
     
    #############################################################################
    class Fenetre(QtGui.QWidget):
     
        cachefen = QtCore.pyqtSignal()  # création d'un nouveau signal
     
        #========================================================================
        def __init__(self, parent=None):
            super(Fenetre, self).__init__(parent)
     
            self.setWindowTitle('Programme test')
            self.setWindowIcon(QtGui.QIcon('icone.png'))
            self.resize(400, 300)
     
        #========================================================================
        def closeEvent(self, event):
            """lancé avec la croix rouge de la fenêtre: demande pour cacher la fenêtre"""
            self.cachefen.emit()  # envoie le signal demandant de cacher la fenêtre
            event.ignore()  # mais ne la ferme pas!
     
    #############################################################################
    class SystemTrayIcon(QtGui.QSystemTrayIcon):
     
        #========================================================================
        def __init__(self, Fenetre, parent=None):
            # icone pour le tray avec la fenêtre cachée"
            self.qicon1 = QtGui.QIcon("icone1.png")
            # icone pour le tray avec la fenêctre affichée
            self.qicon2 = QtGui.QIcon("icone2.png")
            super(SystemTrayIcon, self).__init__(self.qicon1, parent)
     
            #--------------------------------------------------------------------
            # met le 1er icone au lancement du tray avec la fenêtre cachée
            self.setIcon(self.qicon1)
     
            #--------------------------------------------------------------------
            # lance la fenêtre sans affichage
            self.fen = Fenetre()
     
            # un clic gauche sur l'icone du tray affichera la fenêtre
            self.activated.connect(self.affichefenetre)
     
            # se prépare à recevoir de la fenêtre sa demande de la cacher
            self.fen.cachefen.connect(self.cachefenetre)
     
            #--------------------------------------------------------------------
            # crée le menu du tray
            menu = QtGui.QMenu(parent)
            # ferme la fenêtre et quitte le programme tray:
            quitterAction = QtGui.QAction('&Quitter', self)
            quitterAction.triggered.connect(self.quitter)
            menu.addAction(quitterAction)
            self.setContextMenu(menu)
     
        #========================================================================
        def affichefenetre(self, raison=None):
            """clic gauche sur l'icone => affiche la fenêtre au dessus des autres"""
            if raison == QtGui.QSystemTrayIcon.Trigger:
                self.fen.activateWindow()  # affiche au dessus des autres fenêtres
                self.fen.showNormal()  # affiche en mode fenêtre
                self.fen.setFocus(True)
     
                # changement de l'icone du tray
                self.setIcon(self.qicon2)  # affiche l'icone qui accompagne l'affichage de la fenêtre
     
        #========================================================================
        def cachefenetre(self):
            """cache la fenêtre sur sa demande"""
            self.fen.hide()
            self.setIcon(self.qicon1)  # affiche l'icone de départ
     
        #========================================================================
        def quitter(self):
            global app
            reponse = QtGui.QMessageBox.question(None,
                              "Confirmez!",
                              "Voulez-vous vraiment quitter?",
                              QtGui.QMessageBox.Yes,
                              QtGui.QMessageBox.No)
            if reponse == QtGui.QMessageBox.Yes:
                # fermer la fenêtre si elle est encore ouverte
                try:
                    self.fen.close()
                except Exception:
                    pass
                # fermer l'application et arrêter l'exécution
                app.quit()
                sys.exit()
     
     
    #############################################################################
    if __name__ == '__main__':
     
        #========================================================================
        app = QtGui.QApplication(sys.argv)
     
        #========================================================================
        # indispensable pour utiliser QSystemTrayIcon
        # sinon: arret complet après fermeture d'un simple messagebox
        app.setQuitOnLastWindowClosed(False)
     
        #========================================================================
        # fenêtre à lancer
        fen = Fenetre
     
        #========================================================================
        # lancement du tray (c'est lui qui lancera la fenêtre)
        trayIcon = SystemTrayIcon(fen)
        trayIcon.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

Discussions similaires

  1. Probléme d'affichage menu sur IE
    Par wask_ dans le forum Mise en page CSS
    Réponses: 5
    Dernier message: 12/05/2010, 16h46
  2. [Joomla!] [Joomla 1.5] problème d'affichage menu
    Par ragisa dans le forum EDI, CMS, Outils, Scripts et API
    Réponses: 0
    Dernier message: 20/03/2010, 04h33
  3. Problème d'affichage menu CSS
    Par ddl85 dans le forum Mise en page CSS
    Réponses: 5
    Dernier message: 07/10/2009, 15h59
  4. [Menu] Problème d'affichage après redirection
    Par Pfeffer dans le forum Général JavaScript
    Réponses: 3
    Dernier message: 22/03/2006, 21h04

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