Salut a tous
je veux développer une application qui se lance après le démarrage de Windows et qui vient s'afficher dans la barre d'outils à coté de l'horloge
merci d'avance
Salut a tous
je veux développer une application qui se lance après le démarrage de Windows et qui vient s'afficher dans la barre d'outils à coté de l'horloge
merci d'avance
Pourquoi cela serait-il spécifique au langage de programmation?
- W
Bonjour,
Voici un programme qui se lance et laisse une icone vers l'horloge.
ceci nécessite wxpython et trois fichiers d'icones (à voir dans le code)
Il faut donc mettre un raccourci du pyw dans le répertoire de démarrage pour qu'il se lance au démarrage de windows.
Alex
Note : L'arrêt passe par le changement de self.close_state, cela est compliqué, mais visiblement on ne peux demander dans un event de taskbaricon de fermer l'application dans les dernières version de wx. Si quelqu'un à quelque chose de mieux...
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 #!/usr/bin/env python # -*- coding: utf-8 -*- # Application qui se lance en tâche de fond # nécessite des fichiers icones "prog.ico" "horloge.ico" "l.ico" # Lance on_timer() tout les tempsmaj=3000ms (dans ce programme met l'icone horloge.ico et crée un fichier de 100000 lignes) # Lance on_left_dclick() si double click gauche (affiche icone L.ico) # Lance on_right_dclick() si double click droit (arrête l'application) import wx class FrameEmainfo(wx.Frame): """Frame""" def __init__(self, *args, **kwds): """Création de la frame""" kwds["style"] = wx.DEFAULT_FRAME_STYLE^wx.MINIMIZE wx.Frame.__init__(self, *args, **kwds) self.tbiconprog = wx.TaskBarIcon() #Icone self.set_icone("prog.ico",u"Texte du programme...") self.SetTitle("titre") self.timer = wx.Timer(self, 1) self.tempsmaj=3000 # temps MAJ en ms self.close_state=False self.Bind(wx.EVT_TIMER, self.on_timer, self.timer) self.timer.Start(self.tempsmaj) self.on_timer(None) def on_left_dclick(self, event): self.set_icone("l.ico",u"L.") event.Destroy() def on_timer(self, event): """Mise à jour""" if self.close_state : self.on_close() else : self.set_icone("horloge.ico",u"Horloge") with open("test.txt","w") as fw: # simulation de traitement for ligne in range(100000): fw.write(str(ligne)+u"\n") self.set_icone("prog.ico",u"Texte du programme...") def set_icone(self,icone,texte): self.tbiconprog.RemoveIcon() self.icone=wx.Icon(icone, wx.BITMAP_TYPE_ICO) self.tbiconprog.SetIcon(self.icone,texte) self.tbiconprog.Bind(wx.EVT_TASKBAR_LEFT_DCLICK,self.on_left_dclick) # si double clic gauche wx.EVT_TASKBAR_RIGHT_DCLICK(self.tbiconprog, self.on_right_dclick) # si double clic droit def on_right_dclick(self, event): self.close_state=True # Fait un arrêt qui sera récupéré dans le timer car l'arret direct bloque l'application def on_close(self): self.timer.Stop() self.tbiconprog.RemoveIcon() self.tbiconprog.Destroy() self.Destroy() if __name__ == "__main__": app = wx.PySimpleApp(0) wx.InitAllImageHandlers() frame_1 = FrameEmainfo(None, -1, "") app.SetTopWindow(frame_1) app.MainLoop()
Bonjour
il existe d'autre méthode a part celle qui utilise la bibliothèque wx?
Bonjour,
On peut le faire aussi avec la bibliothèque graphique PyQt4/Qt4 en utilisant QSystemTrayIcon.
Si tu es intéressé, dis-le: je peux te montrer comment on fait.
bien sure que oui, il me faut cette astuce!
bien sure que oui, il me faut cette astuce!
j’espère que ce n'est pas compliqué.
Bonjour,
Si ce n'est tkinter ou c'est plus dur ceci est aussi facilement réalisable avec les autre GUI.
Un exemple récent avec PyQT. Mais tyrtamos nous montreras sans doute mieux.
Pour le reste, comme le dit wiztricks, ceci dépend du système et non du langage.
Il existe deux possibilités pour cela :
Mettre un raccourci dans le répertoire Démarrer de l'utilisateur (ou de all users)(1).
Avec Python le répertoire utilisateur se retrouve avec os.path.expanduser, un os.path.join vas permettre de créer le chemin et un os.path.isdir() de vérifier que le chemin existe. Voir os.path donc.
Pour ce qui est du raccourci avec Python cela passe par win32com.client ou ctypes : Un exemple de wiztricks sur le sujet.
Il existe un petit souci avec cette solution : L'UAC. La solution à ceci passe par les taches planifiées de Windows (voir un exemple ici).
Et en Python ?
Pour le raccourci vers schtasks /run /tn nom-tâche pas de souci avec l'exemple de wiztricks.
Pour ce qui est de la création de la tâche je sais le faire en batch (2) mais pas avec win32 ou ctypes. Cela doit être possible mais il vas falloir attendre une autre réponse car je n'est pas de Windows pour tester.
Pour le moment je proposerais de créer la tache avec subprocess tel qu'indiquer dans la FAQ.
Pourquoi tout ceci ?
Cela vas vous permettre d'activer/désactiver le lancement automatique de l'application à partir de son menu contextuel.
Vérifier si la tache existe vas passer par la vérification de stdout de subprocess d'un schtasks /query et pour la vérification de l'existence du lien par os.path.
La solution BDR : Cela passe par HKEY_LOCAL_MACHINE\Software\Microsoft\Windows\CurrentVersion\Run.
Pour Python c'est réalisable avec _winreg par exemple.
@+
(1)
XP : C:\Documents and Settings\$USER$\Menu Démarrer\Programmes\Démarrage
Vista, Seven : C:\Users\$USER$\AppData\Roaming\Microsoft\Windows\Start Menu (ou menu démarrer)\Programs\Startup
Sous Seven et Vista \Users\All Users\Start Menu est un point de jonction qui correspond à ProgramData\Microsoft\Windows\Start Menu.
A étudier donc.
(2) Un copier/coller rapide d'un batch pour l'exemple
Code : Sélectionner tout - Visualiser dans une fenêtre à part
1
2
3
4
5
6
7
8 :CreateSC REM Creation automatique d'un raccourci REM Note: Créer le vbs a la volé comme pour :Notice ? CALL :Apply filename "%UserProfile%\Bureau\%1.lnk" IF NOT EXIST %filename% ( cscript.exe c:\createsc.vbs %1 > NUL ) GOTO :EOFEt pour ce qui est de la création dans le batch
Code : Sélectionner tout - Visualiser dans une fenêtre à part
1
2
3
4
5
6
7
8
9
10 Dim Shell, DesktopPath, SC, oArgs Set oArgs = WScript.Arguments Set Shell = CreateObject("WScript.Shell") DesktopPath = Shell.SpecialFolders("Desktop") Set SC = Shell.CreateShortcut(DesktopPath & "\" & oArgs(0) & ".lnk") SC.TargetPath = "%windir%\system32\shutdown.exe" SC.Arguments = "/A" SC.IconLocation = "%SystemRoot%\system32\SHELL32.dll, 27" SC.WorkingDirectory = "%windir%\system32" SC.Save
Il existe sans doute mieux en batch mais bon... Du moment que cela fonctionne je n'y ai plus toucher...
Code : Sélectionner tout - Visualiser dans une fenêtre à part
1
2
3
4
5
6
7
8
9 :Notice eventcreate /T INFORMATION /L APPLICATION /ID 1 /SO Resetsvr /D "Ouverture de session automatique le %date% %time%" > NUL if %show%==1 ( echo msg = "Le serveur a été démarré le " ^& Date ^& " à " ^& Time > c:\demarragepc.vbs echo MsgBox msg, vbInformation + 4096, "Information serveur" >> c:\demarragepc.vbs cscript.exe c:\demarragepc.vbs >NUL del c:\demarragepc.vbs ) EXIT /b 0
Ce qui est compliqué, c'est d'apprendre à utiliser une bibliothèque graphique! Chacune a sa logique et ses instructions. Dans le choix que tu fais pour le tray, il vaudrait mieux que ce soit la bibliothèque que tu utilises d'habitude pour tes applications!
Admettons que c'est PyQt4. Voilà un code test qui fonctionne de la façon suivante:
- au lancement, une fenêtre s'affiche, et cette fenêtre lance aussi une icone tray. On pourrait aussi faire que seule l'icone tray apparaisse et pas la fenêtre de l'application!
- si on ferme la fenetre (croix en haut à gauche), en fait on désactive son affichage, mais la fenêtre reste active en mémoire.
- si on clique sur l'icone tray, on active de nouveau l'affichage de la fenêtre.
- pour supprimer en même temps la fenêtre et l'icone tray, il faut faire clic-droit sur l'icone tray, il apparait un menu, on choisit l'item "quitter" et on répond "oui" à la question.
Pour que l'application soit lancée au démarrage de windows, il faut la lancer dans le répertoire "démarrage" de Windows. Pour ça, je pense qu'il faut mettre un raccourcis dans "C:\ProgramData\Microsoft\Windows\Start Menu\Programs\Startup" pour Windows 7.
Pour que l'icone tray soit toujours visible à côté de l'horloge, il faut changer sa config: clic droit sur la barre des tâches => propriétés => zone de notification => bouton "personnaliser" => sélectionner l'icone => "afficher l'icone et les notifications".
Bonus: on peut rendre l'application "standalone" avec cx_freeze, ce qui fait que l'application lancée sera un "exe".
Voilà le code test:
Pour exécuter, il faut Python 2.7 et PyQt4 (http://www.riverbankcomputing.co.uk/software/pyqt/intro).
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 #! /usr/bin/python # -*- coding: utf-8 -*- from __future__ import division # Python v2.7 """ lancement d'une fenetre avec une icone tray en plus """ import os, sys from PyQt4 import QtCore, QtGui ############################################################################# class TrayIcon(QtGui.QSystemTrayIcon): #======================================================================== def __init__(self, icone, fenetre, bulle, parent=None): super(TrayIcon, self).__init__(icone, parent) # stockage des arguments self.icone = icone self.fenetre = fenetre self.bulle = bulle # crée le menu clic droit menu = QtGui.QMenu(parent) lancementAction = QtGui.QAction('&Lancement', self) lancementAction.triggered.connect(self.lancement) menu.addAction(lancementAction) aproposAction = QtGui.QAction('&A propos', self) aproposAction.triggered.connect(self.apropos) menu.addAction(aproposAction) quitterAction = QtGui.QAction('&Quitter', self) quitterAction.triggered.connect(self.sortie) menu.addAction(quitterAction) self.setContextMenu(menu) # faire qu'un clic gauche active l'affichage de la fenêtre self.activated.connect(self.visufenetre) # ajoute une bulle d'information self.setToolTip(self.bulle) #======================================================================== def visufenetre(self, raison): """si clic gauche: affiche la fenêtre""" if raison == QtGui.QSystemTrayIcon.Trigger: self.fenetre.show() #======================================================================== def lancement(self): """menu clic droit: affiche la fenêtre""" self.fenetre.show() #======================================================================== def apropos(self): """menu clic droit: fenêtre "à propos" """ QtGui.QMessageBox.information(None, u"A propos", u"A propos du programme") #======================================================================== def sortie(self): """menu clic droit: fermeture de l'application""" reponse = QtGui.QMessageBox.question(None, u"Confirmez!", u"Voulez-vous vraiment quitter?", QtGui.QMessageBox.Yes, QtGui.QMessageBox.No) if reponse == QtGui.QMessageBox.Yes: # fermer la fenêtre self.fenetre.quitter() # fermer l'application QtGui.QApplication.quit() ############################################################################# class Fenetre(QtGui.QWidget): #======================================================================== def __init__(self, parent=None): super(Fenetre, self).__init__(parent) icone = QtGui.QIcon('icone.png') # instruction concernant la fenêtre self.resize(400, 300) self.setWindowIcon(icone) self.setWindowTitle('Programme test') # créer le lineEdit self.lineEdit = QtGui.QLineEdit(self) # positionne les widgets dans la fenêtre posit = QtGui.QGridLayout() posit.addWidget(self.lineEdit, 0, 0) self.setLayout(posit) # initialise l'icone tray bulle = u"Programme test" self.initray(icone, bulle) #======================================================================== def initray(self, icone, bulle): """lance l'icone tray """ # lance le tray self.trayIcon = TrayIcon(icone, self, bulle) self.trayIcon.show() # initialise le drapeau qui dira si un arrêt volontaire est demandé self.ferme = False #======================================================================== def quitter(self): self.ferme = True # arrêt demandé du programme self.close() #======================================================================== def closeEvent(self, event): """ferme la fenêtre ou désactive son affichage""" if self.ferme: event.accept() else: self.hide() event.ignore() ############################################################################# if __name__ == '__main__': # lancement de la bibliothèque graphique app = QtGui.QApplication(sys.argv) # indispensable, sinon: arret après fermeture de la dernière fenêtre app.setQuitOnLastWindowClosed(False) # pour assurer la traduction automatique du conversationnel à la locale locale = QtCore.QLocale.system().name() translator = QtCore.QTranslator () if os.path.splitext(sys.argv[0])[1] in ['.py', '.pyw']: # exécution par l'interpréteur normal reptrad = unicode(QtCore.QLibraryInfo.location(QtCore.QLibraryInfo.TranslationsPath)) else: # exécution de la version exécutable après cx_freeze (ou équivalent): #=>les fichiers de traduction doivent se trouver dans "translations" reptrad = unicode("translations") translator.load(QtCore.QString("qt_") + locale, reptrad) app.installTranslator(translator) # lancement de la fenêtre fen = Fenetre() fen.show() # exécution et boucle de traitement sys.exit(app.exec_())
Je n'ai plus le temps maintenant: si tu as des questions, il faudra attendre ce soir pour la réponse!
Un exemple rapide en gtk
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 #!/usr/bin/python # -*- coding: utf-8 -*- # # import gtk class gtkApp: def __init__(self): self.tray = gtk.StatusIcon() self.tray.set_from_stock(gtk.STOCK_ABOUT) self.tray.connect('popup-menu', self.showmenu) self.tray.set_tooltip(("Exemple d'application dans le systray")) def showmenu(self, icon, eventbutton, eventtime): menu = gtk.Menu() about = gtk.MenuItem("A propos") about.show() menu.append(about) about.connect('activate', self.showabout) quitapp = gtk.MenuItem("Quitter") quitapp.show() menu.append(quitapp) quitapp.connect('activate', gtk.main_quit) menu.popup(None, None, gtk.status_icon_position_menu, eventbutton, eventtime, self.tray) def showabout(self, widget): # Voir gtk.AboutDialog # http://www.pygtk.org/docs/pygtk/class-gtkaboutdialog.html aboutdialog = gtk.AboutDialog() aboutdialog.set_destroy_with_parent(True) aboutdialog.set_name('StatusIcon') aboutdialog.set_comments(("Exemple d'application dans le systray")) aboutdialog.run() aboutdialog.destroy() gtkApp() gtk.main()
Bonjour,
Cette question est "résolue", mais houma2001 pourrait-il dire quelle solution il a retenue?
Bonjour à tous
la 2eme solution me parait efficace,
du moment que je ne maitrise pas pyqt je crois qu'il est tant de s'engager dans ce gui.
merci beaucoup.
Partager