Bonjour,
Je termine une petite application en python avec une interface en tkinter. Je suis dans la phase finition. J'aimerais ajouter une fonctionnalité intéressante: lorsque l'utilisateur passe le curseur de la souris sur certains elements, un popup apparait après x seconds contenant un message, popup qui disparaitrait au moindre mouvement de la souris.
Exemple:
Le screenshot a fait disparaitre le curseur, mais je pense que vous voyez ce que je veux dire.
Corrigez moi si je me trompe mais il n'y a rien de prévu en tkinter pour faire cela de base. En tout cas mes recherches n'ont rien données. J'ai envisagé deux possibilités:
- un toplevel
- un menu
J'ai finalement opté pour un Menu car ce widget peut être placé où l'on veut grâce à la method post(). Voici donc ce que j'ai fait pour le moment:
J'ai plusieurs questions/problèmes avec le code ci-dessus:
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 #!/usr/bin/env python # -*- coding: utf-8 - import Tkinter as tk import ttk import textwrap class HoverInfo(tk.Menu): """ """ def __init__(self, master, text): # Options placed directly here for testing purpose options = {'activebackground': 'SystemHighlight', # Default SystemHighlight 'background': 'SystemMenu', # Default SystemMenu 'selectcolor': 'SystemMenuText', # Default SystemMenuText 'tearoff': 0} # Default 1 tk.Menu.__init__(self, master, **options) self.add_text(text) self._displayed = False master.bind('<Button-3>', self.display) master.bind('<ButtonRelease-3>', self.remove) def add_text(self, text): _text = '\n'.join(textwrap.wrap(text, width=40)) # Do not work self.add_command(label=_text) def display(self, event): if not self._displayed: self._displayed = True self.post(event.x_root, event.y_root) def remove(self, event): if self._displayed: self._displayed = False self.unpost() class MyApp(tk.Frame): """ """ def __init__(self, parent, *args, **kwargs): tk.Frame.__init__(self, parent, *args, **kwargs) label = tk.Label(self, text='Right click here', width=15, height=3) label.pack() hover = HoverInfo(label, "This is a message displayed when mouse's right button is kept pressed") if __name__ == '__main__': root = tk.Tk() app = MyApp(root) app.pack() root.mainloop()
- Il semblerait que bien qu'il existe un binding '<Enter>' pour appeler un callback lorque la souris passe sur l'élément, il n'y a pas d'équivalent lorsqu'on bouge la souris. (seulement '<Leave>' ce qui est génant si l'utilisateur laisse la souris sur l'élement pour remplir un Entry par exemple).
- Ici j'utilise '<ButtonRelease-3>' pour faire disparaitre le Menu folttant. Le menu apparait si on clique droit dessus et disparait lorsqu'on relache le boutton. Compromis acceptable selon moi. Mais bien que cela fonctionne parfaitement sur Linux, python 2.7, même version de tkinter, sur win7 le menu reste affiché lorsque le boutton droit de la souris est relaché. Why?
- Le menu généré est une sorte de "boutton". On peut le "sélectionner" et il devient alors bleu et disparait si on clique gauche dessus. J'aimerais enlever cela (ça ne le fait pas sur linux d'ailleurs).
- Le contenu du popup peut être long (comme dans l'exemple ci-dessus). J'ai pensé à wrapper le texte avec une longeur définie (ici en utilisant textwrap). Mais visiblement on ne peut faire de saut à la ligne dans le text d'un menu...
Est-ce que l'un de vous aurais une idée de comment résoudre l'un des points ci-dessus? Je commence à regretter de ne mettre mis à quelque chose de plus haut niveau comme pyQT ou même wxPython...
Ciao ciao,
Julien
Partager