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

Tkinter Python Discussion :

Synchroniser Scrollbar ?


Sujet :

Tkinter Python

  1. #1
    Membre éprouvé
    Avatar de Luke spywoker
    Homme Profil pro
    Etudiant informatique autodidacte
    Inscrit en
    Juin 2010
    Messages
    1 077
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations professionnelles :
    Activité : Etudiant informatique autodidacte

    Informations forums :
    Inscription : Juin 2010
    Messages : 1 077
    Par défaut Synchroniser Scrollbar ?
    Salut les pythons.
    En prenant mes notes sur PMW je me souvient qu'on pouvait synchroniser des différentes Scrollbar afin que celle-çi défile en meme temps sur la meme position, seulement je ne sais plus ou est l'info dans mes notes.
    Si quelqu'un pourrait me rafraichir la mémoire sa serai sympa.

  2. #2
    Membre Expert Avatar de PauseKawa
    Homme Profil pro
    Technicien Help Desk, maintenance, réseau, système et +
    Inscrit en
    Juin 2006
    Messages
    2 725
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Hérault (Languedoc Roussillon)

    Informations professionnelles :
    Activité : Technicien Help Desk, maintenance, réseau, système et +
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Juin 2006
    Messages : 2 725
    Par défaut
    Bonjour,

    J'ai cela dans mes codes
    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
    #!/usr/bin/env python
    # -*- coding: UTF-8 -*-
    #
    #
    try:
        import Tkinter as Tk
    except:
        import tkinter as Tk
     
    def yview(*args):
        # Sous Python 2 : apply(liste.yview, args)
        if args[0] == 'scroll':
            l1.yview_scroll(args[1], args[2])
            l2.yview_scroll(args[1], args[2])
        elif args[0] == 'moveto':
            l1.yview_moveto(args[1])
            l2.yview_moveto(args[1])
     
    root = Tk.Tk()
    root.title('tk : test Scrollbar')
    s1 = Tk.Scrollbar(root, orient=Tk.VERTICAL)
    s2 = Tk.Scrollbar(root, orient=Tk.VERTICAL)
    l1 = Tk.Listbox(root, yscrollcommand=s1.set)
    l2 = Tk.Listbox(root, yscrollcommand=s2.set)
    for e in range(1000):
        l1.insert(Tk.END, e)
        l2.insert(Tk.END, e)
    l1.pack(side=Tk.LEFT, fill=Tk.BOTH, expand=1)
    s1.config(command=yview)
    s1.pack(side=Tk.LEFT, fill=Tk.Y)
    l2.pack(side=Tk.LEFT, fill=Tk.BOTH, expand=1)
    s2.config(command=yview)
    s2.pack(side=Tk.LEFT, fill=Tk.Y)
    root.mainloop()
    @+

  3. #3
    Membre Expert Avatar de PauseKawa
    Homme Profil pro
    Technicien Help Desk, maintenance, réseau, système et +
    Inscrit en
    Juin 2006
    Messages
    2 725
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Hérault (Languedoc Roussillon)

    Informations professionnelles :
    Activité : Technicien Help Desk, maintenance, réseau, système et +
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Juin 2006
    Messages : 2 725
    Par défaut
    Re,

    J'ai un code plus récent (Note perso : faire le ménage )
    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
    #!/usr/bin/env python
    # -*- coding: UTF-8 -*-
    #
    #
    try:
        import Tkinter as Tk
    except:
        import tkinter as Tk
     
    def yview(*args):
        # Sous Python 2 : apply(liste.yview, args)
        if args[0] == 'scroll':
            l1.yview_scroll(args[1], args[2])
            l2.yview_scroll(args[1], args[2])
        elif args[0] == 'moveto':
            l1.yview_moveto(args[1])
            l2.yview_moveto(args[1])
        elif args[0] == 'sync':
            tosync = l1
            if args[1] == l1:
                tosync = l2
            tosync.yview_moveto(args[1].yview()[0])
     
    root = Tk.Tk()
    root.title('tk : test Scrollbar')
    s1 = Tk.Scrollbar(root, orient=Tk.VERTICAL)
    s2 = Tk.Scrollbar(root, orient=Tk.VERTICAL)
    l1 = Tk.Listbox(root, yscrollcommand=s1.set)
    l2 = Tk.Listbox(root, yscrollcommand=s2.set)
    for e in range(1000):
        l1.insert(Tk.END, e)
        l2.insert(Tk.END, e)
    l1.pack(side=Tk.LEFT, fill=Tk.BOTH, expand=1)
    s1.config(command=yview)
    s1.pack(side=Tk.LEFT, fill=Tk.Y)
    l2.pack(side=Tk.LEFT, fill=Tk.BOTH, expand=1)
    s2.config(command=yview)
    s2.pack(side=Tk.LEFT, fill=Tk.Y)
    #listbox.bind('<Button-4>', lambda event: event.widget.yview_scroll(-1, UNITS))
    #listbox.bind('<Button-5>', lambda event: event.widget.yview_scroll(1, UNITS))
    root.bind('<Button-4>', lambda event: yview('sync', event.widget))
    root.bind('<Button-5>', lambda event: yview('sync', event.widget))
    root.bind('<Prior>', lambda event: yview('scroll', -1, 'pages'))
    root.bind('<Next>', lambda event: yview('scroll', 1, 'pages'))
    root.bind('<Up>', lambda event: yview('scroll', -1, 'units'))
    root.bind('<Down>', lambda event: yview('scroll', 1, 'units'))
    root.mainloop()
    @+

  4. #4
    Membre éprouvé
    Avatar de Luke spywoker
    Homme Profil pro
    Etudiant informatique autodidacte
    Inscrit en
    Juin 2010
    Messages
    1 077
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations professionnelles :
    Activité : Etudiant informatique autodidacte

    Informations forums :
    Inscription : Juin 2010
    Messages : 1 077
    Par défaut
    Merci ton code fonctionne parfaitement, je vais le réutiliser a ma manière si j'ai ton autorisation, mais n'y a t il pas une solution plus générique (genre méthode ou attribut spécialiser car il me semble avoir lu quelque part...) qu'un parfait bricolage (de la programmation de haut niveau) fonctionnant parfaitement sous python mais pas sous pyshell...: les Listbox ne se remplissent pas:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
     
    Traceback (most recent call last):
      File "<input>", line 2, in <module>
      File "/usr/lib/python2.6/lib-tk/Tkinter.py", line 2512, in insert
        self.tk.call((self._w, 'insert', index) + elements)
    TclError: invalid command name ".26383136"
    Grand merci j'espère avoir ton aval pour réutiliser le code.

  5. #5
    Membre Expert Avatar de PauseKawa
    Homme Profil pro
    Technicien Help Desk, maintenance, réseau, système et +
    Inscrit en
    Juin 2006
    Messages
    2 725
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Hérault (Languedoc Roussillon)

    Informations professionnelles :
    Activité : Technicien Help Desk, maintenance, réseau, système et +
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Juin 2006
    Messages : 2 725
    Par défaut
    Bonjour,

    Il y a bien apply(liste.yview, args) (voir le commentaire dans le code et un exemple (incomplet), une seule Scrollbar pour deux Widgets sur le même principe ici ) mais cela ne fonctionne pas sous Python 3 (apply(fonction, args) deviens fonction(*args) et apply n'existe plus).
    Pas de problème pour l'utilisation du code.
    Il y a sans doute une autre façon de faire mais dans le cas présent je voulais centraliser tout dans la fonction, principalement le bind de la roulette de la souris.
    Pas terrible qu'insert ne trouve pas le Widget sous pyshell...

    @+

  6. #6
    Membre Expert Avatar de PauseKawa
    Homme Profil pro
    Technicien Help Desk, maintenance, réseau, système et +
    Inscrit en
    Juin 2006
    Messages
    2 725
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Hérault (Languedoc Roussillon)

    Informations professionnelles :
    Activité : Technicien Help Desk, maintenance, réseau, système et +
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Juin 2006
    Messages : 2 725
    Par défaut
    Re,

    Pour pyshell essai de remplir les listbox juste avant le mainloop() pour voir.

    @++

  7. #7
    Membre éprouvé
    Avatar de Luke spywoker
    Homme Profil pro
    Etudiant informatique autodidacte
    Inscrit en
    Juin 2010
    Messages
    1 077
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations professionnelles :
    Activité : Etudiant informatique autodidacte

    Informations forums :
    Inscription : Juin 2010
    Messages : 1 077
    Par défaut
    Pause kawa tu est un grand programmeur car pour savoir que la fonction argument de command prend 3 arguments en l'occurence args[0] la méthode de scrolling, args[1] les unités et args [2] la définition d'interprétation des unités...(premier script)
    si j'avais tenter un bricolage je n'y serai pas arriver mais je pensais qu'il existait une méthode|option générique pour synchroniser les Scrollbar avant de me lancer.
    Mais j'ai redéfinis la fonction yview(args) en lui donnant un autre nom et remplacer l1 et l2 par mes widgets, sa marche aussi je t'ai copier et je suis a bonne école.

    Est-ce-que 'sync' est une méthode de scrolling ou l'a tu inventer ?

    Encore merci du coup de main.

  8. #8
    Membre Expert Avatar de PauseKawa
    Homme Profil pro
    Technicien Help Desk, maintenance, réseau, système et +
    Inscrit en
    Juin 2006
    Messages
    2 725
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Hérault (Languedoc Roussillon)

    Informations professionnelles :
    Activité : Technicien Help Desk, maintenance, réseau, système et +
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Juin 2006
    Messages : 2 725
    Par défaut
    Il n'y a que 'scroll' et 'moveto'.
    scroll a deux arguments, la position et la mesure ('pages', 'units' > (WHAT))
    self.tk.call(self._w, 'xview', 'scroll', number, what)
    moveto un seul
    self.tk.call(self._w, 'yview', 'moveto', fraction)
    'sync' n'existe pas. Sans passer par ce code la liste qui a le focus vas deux fois plus vite : le mouvement de la roulette + la fonction yview.

  9. #9
    Membre Expert Avatar de PauseKawa
    Homme Profil pro
    Technicien Help Desk, maintenance, réseau, système et +
    Inscrit en
    Juin 2006
    Messages
    2 725
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Hérault (Languedoc Roussillon)

    Informations professionnelles :
    Activité : Technicien Help Desk, maintenance, réseau, système et +
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Juin 2006
    Messages : 2 725
    Par défaut
    Et bien en fait merci Luke spywoker: Il y avait un bug dans le code présenté.
    De même que pour
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    root.bind('<Button-4>', lambda event: yview('sync', event.widget))
    root.bind('<Button-5>', lambda event: yview('sync', event.widget))
    Les events '<Prior>', '<Next>' sont doublés pour le Widget qui a le focus. Ils sont interprétés une première fois par l'interpréteur Tcl/Tk puis passent par la fonction
    Le fait de manipuler un petit nombre de données cache l'effet.
    Voici un code qui devrais corriger la chose:
    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
    #!/usr/bin/env python
    # -*- coding: UTF-8 -*-
    #
    #
    try:
        import Tkinter as Tk
    except:
        import tkinter as Tk
     
    def yview(*args):
        # Sous Python 2 : apply(liste.yview, args)
        if args[0] == 'scroll':
            l1.yview_scroll(args[1], args[2])
            l2.yview_scroll(args[1], args[2])
        elif args[0] == 'moveto':
            l1.yview_moveto(args[1])
            l2.yview_moveto(args[1])
        elif args[0] == 'sync':
            if args[1] in (l1, l2): # Le bind est sur root qui n'as pas de méthode .yview(). Plantage assuré si le focus n'est pas sur une des listes
                tosync = l1
                if args[1] == l1:
                    tosync = l2
                tosync.yview_moveto(args[1].yview()[0])
     
    root = Tk.Tk()
    root.title('tk : test Scrollbar')
    s1 = Tk.Scrollbar(root, orient=Tk.VERTICAL)
    s2 = Tk.Scrollbar(root, orient=Tk.VERTICAL)
    l1 = Tk.Listbox(root, yscrollcommand=s1.set)
    l2 = Tk.Listbox(root, yscrollcommand=s2.set)
    for e in range(10000):
        l1.insert(Tk.END, e)
        l2.insert(Tk.END, e)
    l1.pack(side=Tk.LEFT, fill=Tk.BOTH, expand=1)
    s1.config(command=yview)
    s1.pack(side=Tk.LEFT, fill=Tk.Y)
    l2.pack(side=Tk.LEFT, fill=Tk.BOTH, expand=1)
    s2.config(command=yview)
    s2.pack(side=Tk.LEFT, fill=Tk.Y)
    #listbox.bind('<Button-4>', lambda event: event.widget.yview_scroll(-1, UNITS))
    #listbox.bind('<Button-5>', lambda event: event.widget.yview_scroll(1, UNITS))
    root.bind('<Button-4>', lambda event: yview('sync', event.widget))
    root.bind('<Button-5>', lambda event: yview('sync', event.widget))
    root.bind('<Prior>', lambda event: yview('sync', event.widget)) # <<<
    root.bind('<Next>', lambda event: yview('sync', event.widget)) # <<<
    root.bind('<Up>', lambda event: yview('scroll', -1, 'units'))
    root.bind('<Down>', lambda event: yview('scroll', 1, 'units'))
    root.mainloop()
    @+

    Edit: Pas '<Up>' et '<Down>'

+ Répondre à la discussion
Cette discussion est résolue.

Discussions similaires

  1. Synchroniser Scrollbar avec son contenu
    Par maVariable dans le forum Windows Forms
    Réponses: 1
    Dernier message: 10/06/2009, 18h29
  2. comment synchroniser un Label et une Scrollbar?
    Par wrm8787 dans le forum Macros et VBA Excel
    Réponses: 2
    Dernier message: 07/04/2009, 15h01
  3. Javascript Scrollbar Synchronisation Div
    Par Maveck dans le forum Général JavaScript
    Réponses: 6
    Dernier message: 01/09/2008, 15h26
  4. synchroniser 2 scrollbar horizontale sur 2 listbox
    Par oddis dans le forum VB 6 et antérieur
    Réponses: 7
    Dernier message: 29/11/2006, 14h42
  5. [Listbox] ScrollBar Horizontal
    Par haleem dans le forum VB 6 et antérieur
    Réponses: 4
    Dernier message: 20/04/2005, 07h53

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