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 :

Scrollbar root Tkinter [Python 3.X]


Sujet :

Tkinter Python

  1. #1
    Membre habitué
    Homme Profil pro
    Étudiant
    Inscrit en
    Juillet 2016
    Messages
    132
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 26
    Localisation : France, Indre et Loire (Centre)

    Informations professionnelles :
    Activité : Étudiant
    Secteur : Industrie

    Informations forums :
    Inscription : Juillet 2016
    Messages : 132
    Points : 130
    Points
    130
    Par défaut Scrollbar root Tkinter
    Bonjour,

    J'aimerais faire apparaitre une scrollbar verticale et/ou horizontal quand le root depasse une certaine taille fixée.
    Pour plus de précisions : j'ai une frame qui contient plusieurs objets à l'intérieur, et du coup pour ne pas que ça depasse de l'écran j'aimerais mettre une taille maximale à partir de laquelle on pourrait scroll down la frame en question via une scrollbar dans le root.

    Merci d'avance pour vos informations et votre aide.

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

    Vous pourriez vous inspirer de cet exemple.

    - W
    Architectures post-modernes.
    Python sur DVP c'est aussi des FAQs, des cours et tutoriels

  3. #3
    Membre habitué
    Homme Profil pro
    Étudiant
    Inscrit en
    Juillet 2016
    Messages
    132
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 26
    Localisation : France, Indre et Loire (Centre)

    Informations professionnelles :
    Activité : Étudiant
    Secteur : Industrie

    Informations forums :
    Inscription : Juillet 2016
    Messages : 132
    Points : 130
    Points
    130
    Par défaut
    Merci pour votre réponse,

    Cette class convient parfaitement à ma situation.

    Cependant, les frames dans mon canvas peuvent grandir ou se créer, et la scrollbar ne suit pas ..
    de plus quand on intéragit avec les frames a l'intérieur du canvas un rebord gris apparaît.

    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
    from tkinter import *
     
    class AutoScrollbar(Scrollbar):
        # a scrollbar that hides itself if it's not needed.  only
        # works if you use the grid geometry manager.
        def set(self, lo, hi):
            if float(lo) <= 0.0 and float(hi) >= 1.0:
                # grid_remove is currently missing from Tkinter!
                self.tk.call("grid", "remove", self)
            else:
                self.grid()
            Scrollbar.set(self, lo, hi)
        def pack(self, **kw):
            raise(TclError, "cannot use pack with this widget")
        def place(self, **kw):
            raise (TclError, "cannot use place with this widget")
     
    global root,frame
    root = Tk()
     
    vscrollbar = AutoScrollbar(root)
    vscrollbar.grid(row=0, column=1, sticky=N+S)
    hscrollbar = AutoScrollbar(root, orient=HORIZONTAL)
    hscrollbar.grid(row=1, column=0, sticky=E+W)
     
    canvas = Canvas(root,
                    yscrollcommand=vscrollbar.set,
                    xscrollcommand=hscrollbar.set)
    canvas.grid(row=0, column=0, sticky=N+S+E+W)
     
    vscrollbar.config(command=canvas.yview)
    hscrollbar.config(command=canvas.xview)
     
    # make the canvas expandable
    root.grid_rowconfigure(0, weight=1)
    root.grid_columnconfigure(0, weight=1)
     
    #
    # create canvas contents
     
    frame = Frame(canvas)
    #frame.rowconfigure(1, weight=1)
    #frame.columnconfigure(1, weight=1)
    def creation(frame):
        for i in range(4,15):
            button = Button(frame, padx=7, pady=7, text="[%d]" % i)
            button.grid(row=i, column=0, sticky='news')
    rows = 5
    for i in range(1,rows):
        for j in range(1,10):
            button = Button(frame, padx=7, pady=7, text="[%d,%d]" % (i,j),command=lambda: creation(frame))
            button.grid(row=i, column=j, sticky='news')
     
     
    canvas.create_window(0, 0, anchor=NW, window=frame,state=NORMAL)
    frame.update_idletasks()
     
    canvas.config(scrollregion=canvas.bbox("all"))
     
    root.mainloop()
    Si on fait apparaitre plus de boutons, la scrollbar n'apparait pas.
    Alors d'après ce que j'ai essayé il faut suffit d'actualiser la zone à affecter la scrollbar quand on ajoute des objets qui dépasse du root avec :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    canvas.config(scrollregion=canvas.bbox("all"))
    Cependant ce sont des class qui font de nouveaux objets dans mon programme je ne peux donc pas appeller le canvas dedans vu qu'il n'est pas encore créé.
    Est ce qu'une fonction qui détecte le clic en boucle pour "actualiser" ce paramètre peut être envisageable ?

    Merci d'avance.

  4. #4
    Membre confirmé

    Homme Profil pro
    Bidouilleur
    Inscrit en
    Avril 2016
    Messages
    721
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Paris (Île de France)

    Informations professionnelles :
    Activité : Bidouilleur

    Informations forums :
    Inscription : Avril 2016
    Messages : 721
    Points : 503
    Points
    503
    Billets dans le blog
    1
    Par défaut
    Je me demande bien quel genre d'application c'est pour créer des widgets tkinter ainsi.

    En ce qui concerne ton problème qui est assez vague, car je comprends pas trop le dessein de la chose si tu crées des widget dont le parent n'a pas été créé.

    Je dirais comme ça de surcharger la méthode grid, ce qui à chaque ajout d'élément dans ta frame tenterait une mise à jour du canevas si existant, dont l'instance pourrait être éventuellement stockée dans une variable de classe.
    Le temps ronge l'amour comme l'acide.

  5. #5
    Membre habitué
    Homme Profil pro
    Étudiant
    Inscrit en
    Juillet 2016
    Messages
    132
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 26
    Localisation : France, Indre et Loire (Centre)

    Informations professionnelles :
    Activité : Étudiant
    Secteur : Industrie

    Informations forums :
    Inscription : Juillet 2016
    Messages : 132
    Points : 130
    Points
    130
    Par défaut
    Bonjour,

    Enfaite ma class permet de creer des frames dans une frame déjà existente. J'y rajoute ensuite des boutons ect mais ce n'est pas important finalement.
    Je ne sais pas si tu as essayé le programme que j'ai mis mais il illustre plutot bien le problème.

    Les boutons supplémentaires créés par la command sortent de la zone du root et la scrollbar ne les prend pas du tout en compte.
    il faut réutiliser la fonction config pour finalement reconfigurer le nouveau 'all'.

    Du coup pour l'adaptation à mon programme je ne peux pas faire intervenir le canvas dans ma class vu que je le creer dans la suite de mon programme pour mettre les frames où la class va elle même pouvoir creer des frames. A la inception

    Je sais pas si c'est plus clair, en tout cas merci de ta réponse.

  6. #6
    Membre confirmé

    Homme Profil pro
    Bidouilleur
    Inscrit en
    Avril 2016
    Messages
    721
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Paris (Île de France)

    Informations professionnelles :
    Activité : Bidouilleur

    Informations forums :
    Inscription : Avril 2016
    Messages : 721
    Points : 503
    Points
    503
    Billets dans le blog
    1
    Par défaut
    J'ai regardé, et en fait c'est assez simple en utilisant un event (Configure).

    Exemple avec une classe bricolée selon le code de effbot.

    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
    import tkinter as tk
     
    class AutoScrollbar(tk.Scrollbar):
        # a scrollbar that hides itself if it's not needed.  only
        # works if you use the grid geometry manager.
        def set(self, lo, hi):
            if float(lo) <= 0.0 and float(hi) >= 1.0:
                # grid_remove is currently missing from Tkinter!
                self.tk.call("grid", "remove", self)
            else:
                self.grid()
            tk.Scrollbar.set(self, lo, hi)
     
    class MaFrame(tk.Frame) :
        def __init__(self, parent) :
            self._vscrollbar = AutoScrollbar(parent)
            self._vscrollbar.grid(row=0, column=1, sticky=tk.NS)
            self._hscrollbar = AutoScrollbar(parent, orient=tk.HORIZONTAL)
            self._hscrollbar.grid(row=1, column=0, sticky=tk.EW)
            self._can = tk.Canvas(parent, bg='red',
                                  yscrollcommand=self._vscrollbar.set,
                                  xscrollcommand=self._hscrollbar.set)
     
            self._can.grid(row=0, column=0, sticky=tk.NSEW)
            self._vscrollbar.config(command=self._can.yview)
            self._hscrollbar.config(command=self._can.xview)
     
            super().__init__(self._can)
            self._can.create_window(0, 0, anchor=tk.NW, window=self, state=tk.NORMAL)
            self.bind('<Configure>', self._actualiserDimension)
     
        def _actualiserDimension(self, evt) :
            self._can.config(scrollregion=self._can.bbox("all"))
     
        def grid(self, **dargs) :
            ''' Ne pas grid la Frame '''
            pass
     
     
    root = tk.Tk()
     
    root.grid_rowconfigure(0, weight=1)
    root.grid_columnconfigure(0, weight=1)
     
    frame = MaFrame(root)
     
    def creer():
        for i in range(11, 20):
            button = tk.Button(frame, padx=7, pady=7, text="[%d]" % i)
            button.grid(row=i, column=0, sticky='news')
     
    rows = 5
    for i in range(1,rows):
        for j in range(1,10):
            button = tk.Button(frame, padx=7, pady=7, text="[%d,%d]" % (i,j), command=creer)
            button.grid(row=i, column=j, sticky='news')
     
    root.mainloop()
    Le temps ronge l'amour comme l'acide.

  7. #7
    Membre habitué
    Homme Profil pro
    Étudiant
    Inscrit en
    Juillet 2016
    Messages
    132
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 26
    Localisation : France, Indre et Loire (Centre)

    Informations professionnelles :
    Activité : Étudiant
    Secteur : Industrie

    Informations forums :
    Inscription : Juillet 2016
    Messages : 132
    Points : 130
    Points
    130
    Par défaut
    Bonjour,

    Merci pour ta réponse.

    L'event configure permet de savoir quand l'objet change de configuration c'est ça ?

    Sinon j'ai compris l'idée j'avais binder sur le clic de la souris, c'était pas terrible ^^ merci.
    Est ce que je pourrais avoir un peu plus d'information sur cette petite partie :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
        def grid(self, **dargs) :
            ''' Ne pas grid la Frame '''
            pass
    qu'est ce que veux dire **dargs j'ai vu aussi qu'il existait *args ?

    Cependant j'ai du mal avec l'affichage et plusieurs frames sur des pages différentes. J'ai fait un petit exemple :
    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
    import tkinter as tk
     
    class AutoScrollbar(tk.Scrollbar):
        # a scrollbar that hides itself if it's not needed.  only
        # works if you use the grid geometry manager.
        def set(self, lo, hi):
            if float(lo) <= 0.0 and float(hi) >= 1.0:
                # grid_remove is currently missing from Tkinter!
                self.tk.call("grid", "remove", self)
            else:
                self.grid()
            tk.Scrollbar.set(self, lo, hi)
     
    class MaFrame(tk.Frame) :
        def __init__(self, parent) :
            self._vscrollbar = AutoScrollbar(parent)
            self._vscrollbar.grid(row=0, column=1, sticky=tk.NS)
            self._hscrollbar = AutoScrollbar(parent, orient=tk.HORIZONTAL)
            self._hscrollbar.grid(row=1, column=0, sticky=tk.EW)
            self._can = tk.Canvas(parent, bg='red',
                                  yscrollcommand=self._vscrollbar.set,
                                  xscrollcommand=self._hscrollbar.set)
     
            self._can.grid(row=0, column=0, sticky=tk.NSEW)
            self._vscrollbar.config(command=self._can.yview)
            self._hscrollbar.config(command=self._can.xview)
     
            super().__init__(self._can)
            self._can.create_window(0, 0, anchor=tk.NW, window=self, state=tk.HIDDEN)
            self.bind('<Configure>', self._actualiserDimension)
     
        def _actualiserDimension(self, evt) :
            self._can.config(scrollregion=self._can.bbox("all"))
     
        def grid(self, **dargs) :
            ''' Ne pas grid la Frame '''
            pass
     
     
    root = tk.Tk()
     
    root.grid_rowconfigure(0, weight=1)
    root.grid_columnconfigure(0, weight=1)
     
    frame = MaFrame(root)
    frame2 = MaFrame(root)
     
    def creer():
        for i in range(11, 20):
            button = tk.Button(frame, padx=7, pady=7, text="[%d]" % i)
            button.grid(row=i, column=0, sticky='news')
     
    def continuer():   
        frame._can.create_window(0, 0, anchor=tk.NW, window=frame, state=tk.HIDDEN)
        frame2._can.create_window(0, 0, anchor=tk.NW, window=frame2, state=tk.NORMAL)
     
    button = tk.Button(frame, padx=7, pady=7, text="creer bouton", command=creer)
    button.grid(row=00, column=0, sticky='news')
    button2 = tk.Button(frame, padx=7, pady=7, text="next", command=continuer)
    button2.grid(row=0, column=1, sticky='news')
    button3 = tk.Button(frame2, padx=7, pady=7, text="coucou")
    button3.grid(row=0, column=0, sticky='news')
    frame._can.create_window(0, 0, anchor=tk.NW, window=frame, state=tk.NORMAL)
     
    root.mainloop()
    Y'a pas de pack() ou forget() possible au niveau des frames ?

    Merci d'avance.

  8. #8
    Membre confirmé

    Homme Profil pro
    Bidouilleur
    Inscrit en
    Avril 2016
    Messages
    721
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Paris (Île de France)

    Informations professionnelles :
    Activité : Bidouilleur

    Informations forums :
    Inscription : Avril 2016
    Messages : 721
    Points : 503
    Points
    503
    Billets dans le blog
    1
    Par défaut
    Salut.

    Citation Envoyé par StabiloHB Voir le message
    L'event configure permet de savoir quand l'objet change de configuration c'est ça ?
    Lorsque la dimension du widget a été modifiée, oui.

    Citation Envoyé par StabiloHB Voir le message
    Sinon j'ai compris l'idée j'avais binder sur le clic de la souris, c'était pas terrible ^^ merci.
    Est ce que je pourrais avoir un peu plus d'information sur cette petite partie :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
        def grid(self, **dargs) :
            ''' Ne pas grid la Frame '''
            pass
    qu'est ce que veux dire **dargs j'ai vu aussi qu'il existait *args ?
    C'est une base de python ça
    http://deusyss.developpez.com/tutori...n/args_kwargs/

    Oui j'utilise dargs au lieu de la « norme » kwargs, kw, c'est mon côté rebelle

    Citation Envoyé par StabiloHB Voir le message
    Cependant j'ai du mal avec l'affichage et plusieurs frames sur des pages différentes. J'ai fait un petit exemple :


    Y'a pas de pack() ou forget() possible au niveau des frames ?

    Merci d'avance.
    Bah si, grid_forget, grid_remove
    Trouve-toi une bonne documentation tkinter.

    Si t'as besoin d'accéder à beaucoup de méthode du canvas, ce serait plus simple de modifier cet exemple de classe non plus en la faisant hériter de Frame mais de Canvas.

    Mais le plus simple serait pour l'instant non pas d'agir sur les méthodes de cette classe, mais sur un conteneur.

    En gardant le code de la classe que je t'ai mis précédemment, cela donnerait :

    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
    root = tk.Tk()
     
    root.grid_rowconfigure(0, weight=1)
    root.grid_columnconfigure(0, weight=1)
     
    cadreA = tk.Frame(root)
    frame = MaFrame(cadreA)
    cadreA.grid()
     
    cadreB = tk.Frame(root)
    frame2 = MaFrame(cadreB)
     
    def creer():
        for i in range(11, 20):
            button = tk.Button(frame, padx=7, pady=7, text="[%d]" % i)
            button.grid(row=i, column=0, sticky='news')
     
    def continuer():
        cadreA.grid_forget()
        cadreB.grid()
     
    button = tk.Button(frame, padx=7, pady=7, text="creer bouton", command=creer)
    button.grid(row=0, column=0, sticky='news')
     
    button2 = tk.Button(frame, padx=7, pady=7, text="next", command=continuer)
    button2.grid(row=0, column=1, sticky='news')
     
    button3 = tk.Button(frame2, padx=7, pady=7, text="coucou")
    button3.grid(row=0, column=0, sticky='news')
     
    root.mainloop()
    Le temps ronge l'amour comme l'acide.

  9. #9
    Membre habitué
    Homme Profil pro
    Étudiant
    Inscrit en
    Juillet 2016
    Messages
    132
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 26
    Localisation : France, Indre et Loire (Centre)

    Informations professionnelles :
    Activité : Étudiant
    Secteur : Industrie

    Informations forums :
    Inscription : Juillet 2016
    Messages : 132
    Points : 130
    Points
    130
    Par défaut
    Merci pour la doc ^^
    **dargs, 'd' pour double arguments du coup ?

    Sinon pour ton code je ne comprends pas pourquoi on est obligé de créer 2 cadres pour remettre ensuite le frame dedans, surtout que l'on perd totalement l'interet du programme vu que l'on fixe la scrollbar au root.
    Quand on modifie le root ca ne modifie pas la taille du Canvas donc la scrollbar n'apparait plus. Ne vaut il pas mieux fixer le canvas au root ?
    Quand je fais ça, comme dans l'exemple que j'ai envoyé, je n'arrive pas à faire grid la bonne frame.
    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
    import tkinter as tk
     
    class AutoScrollbar(tk.Scrollbar):
        # a scrollbar that hides itself if it's not needed.  only
        # works if you use the grid geometry manager.
        def set(self, lo, hi):
            if float(lo) <= 0.0 and float(hi) >= 1.0:
                # grid_remove is currently missing from Tkinter!
                self.tk.call("grid", "remove", self)
            else:
                self.grid()
            tk.Scrollbar.set(self, lo, hi)
     
    class MaFrame(tk.Frame) :
        def __init__(self, parent) :
            self._vscrollbar = AutoScrollbar(parent)
            self._vscrollbar.grid(row=0, column=1, sticky=tk.NS)
            self._hscrollbar = AutoScrollbar(parent, orient=tk.HORIZONTAL)
            self._hscrollbar.grid(row=1, column=0, sticky=tk.EW)
            self._can = tk.Canvas(parent, bg='red',
                                  yscrollcommand=self._vscrollbar.set,
                                  xscrollcommand=self._hscrollbar.set)
     
            self._can.grid(row=0, column=0, sticky=tk.NSEW)
            self._vscrollbar.config(command=self._can.yview)
            self._hscrollbar.config(command=self._can.xview)
     
            super().__init__(self._can)
            self._can.create_window(0, 0, anchor=tk.NW, window=self, state=tk.NORMAL)
            self.bind('<Configure>', self._actualiserDimension)
     
        def _actualiserDimension(self, evt) :
            self._can.config(scrollregion=self._can.bbox("all"))
     
        def grid(self, **dargs) :
            ''' Ne pas grid la Frame '''
            pass
     
     
    root = tk.Tk()
     
    root.grid_rowconfigure(0, weight=1)
    root.grid_columnconfigure(0, weight=1)
     
    frame = MaFrame(root)
    frame.grid()
     
    frame2 = MaFrame(root)
     
    def creer():
        for i in range(11, 20):
            button = tk.Button(frame, padx=7, pady=7, text="[%d]" % i)
            button.grid(row=i, column=0, sticky='news')
     
    def continuer():   
        frame.grid_forget()
        frame2.grid()
     
     
    button = tk.Button(frame, padx=7, pady=7, text="creer bouton", command=creer)
    button.grid(row=00, column=0, sticky='news')
     
    button2 = tk.Button(frame, padx=7, pady=7, text="next", command=continuer)
    button2.grid(row=0, column=1, sticky='news')
     
    button3 = tk.Button(frame2, padx=7, pady=7, text="coucou")
    button3.grid(row=0, column=0, sticky='news')
     
     
    root.mainloop()
    Je me trompe ?

  10. #10
    Membre confirmé

    Homme Profil pro
    Bidouilleur
    Inscrit en
    Avril 2016
    Messages
    721
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Paris (Île de France)

    Informations professionnelles :
    Activité : Bidouilleur

    Informations forums :
    Inscription : Avril 2016
    Messages : 721
    Points : 503
    Points
    503
    Billets dans le blog
    1
    Par défaut
    Bah j'avais pas compris que tu voulais garder un unique cadre avec scrollbar, car tu avais créés 2 frames, donc cela impliquait 2 cadres distincts avec scrollbars.

    C'est pas bien clair ce que tu veux faire.
    Le temps ronge l'amour comme l'acide.

  11. #11
    Membre habitué
    Homme Profil pro
    Étudiant
    Inscrit en
    Juillet 2016
    Messages
    132
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 26
    Localisation : France, Indre et Loire (Centre)

    Informations professionnelles :
    Activité : Étudiant
    Secteur : Industrie

    Informations forums :
    Inscription : Juillet 2016
    Messages : 132
    Points : 130
    Points
    130
    Par défaut
    Un petit logiciel avec plusieurs pages, 1 page = 1 frame. Comme ton exemple finalement sauf qu'avec ton code l'appartion de la scrollbar quand tu redimentionne la fenetre ne marche plus comme dans l'exemple de effbot.

    Merci d'avance pour ta réponse

  12. #12
    Membre confirmé

    Homme Profil pro
    Bidouilleur
    Inscrit en
    Avril 2016
    Messages
    721
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Paris (Île de France)

    Informations professionnelles :
    Activité : Bidouilleur

    Informations forums :
    Inscription : Avril 2016
    Messages : 721
    Points : 503
    Points
    503
    Billets dans le blog
    1
    Par défaut
    La scrollbar n’apparaît plus car le contenu n'excède plus la taille de la fenêtre, ajoute du contenu, par ex :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    def continuer():
        cadreA.grid_forget()
        cadreB.grid()
        for i in range(1, 10):
            for j in range(10):
                button = tk.Button(frame2, padx=7, pady=7, text="[%d,%d]" % (i,j))
                button.grid(row=i, column=j, sticky='news')
    tu verras que les scrollbars apparaîtront bien.
    Le temps ronge l'amour comme l'acide.

  13. #13
    Membre habitué
    Homme Profil pro
    Étudiant
    Inscrit en
    Juillet 2016
    Messages
    132
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 26
    Localisation : France, Indre et Loire (Centre)

    Informations professionnelles :
    Activité : Étudiant
    Secteur : Industrie

    Informations forums :
    Inscription : Juillet 2016
    Messages : 132
    Points : 130
    Points
    130
    Par défaut
    Je parle d'un redimentionnement manuel du root, avec la souris. La scrollbar n'apparait plus.
    Pas comme dans cet exemple :
    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
    import tkinter as tk
     
    class AutoScrollbar(tk.Scrollbar):
        # a scrollbar that hides itself if it's not needed.  only
        # works if you use the grid geometry manager.
        def set(self, lo, hi):
            if float(lo) <= 0.0 and float(hi) >= 1.0:
                # grid_remove is currently missing from Tkinter!
                self.tk.call("grid", "remove", self)
            else:
                self.grid()
            tk.Scrollbar.set(self, lo, hi)
     
    class MaFrame(tk.Frame) :
        def __init__(self, parent) :
            self._vscrollbar = AutoScrollbar(parent)
            self._vscrollbar.grid(row=0, column=1, sticky=tk.NS)
            self._hscrollbar = AutoScrollbar(parent, orient=tk.HORIZONTAL)
            self._hscrollbar.grid(row=1, column=0, sticky=tk.EW)
            self._can = tk.Canvas(parent, bg='red',
                                  yscrollcommand=self._vscrollbar.set,
                                  xscrollcommand=self._hscrollbar.set)
     
            self._can.grid(row=0, column=0, sticky=tk.NSEW)
            self._vscrollbar.config(command=self._can.yview)
            self._hscrollbar.config(command=self._can.xview)
     
            super().__init__(self._can)
            self._can.create_window(0, 0, anchor=tk.NW, window=self, state=tk.NORMAL)
            self.bind('<Configure>', self._actualiserDimension)
     
        def _actualiserDimension(self, evt) :
            self._can.config(scrollregion=self._can.bbox("all"))
     
        def grid(self, **dargs) :
            ''' Ne pas grid la Frame '''
            pass
     
     
    root = tk.Tk()
     
    root.grid_rowconfigure(0, weight=1)
    root.grid_columnconfigure(0, weight=1)
     
    frame = MaFrame(root)
     
    def creer():
        for i in range(11, 20):
            button = tk.Button(frame, padx=7, pady=7, text="[%d]" % i)
            button.grid(row=i, column=0, sticky='news')
     
    rows = 5
    for i in range(1,rows):
        for j in range(1,10):
            button = tk.Button(frame, padx=7, pady=7, text="[%d,%d]" % (i,j), command=creer)
            button.grid(row=i, column=j, sticky='news')
     
    root.mainloop()
    Ici la fenetre s'adapte par rapport a sa taille initiale et fait apparaitre des scrollbar quand on la retrécit manuellement, ou quand d'autres objets viennent agrandir la fenetre.

    cependant je n'arrive pas a mettre en place le fait de pouvoir faire une autre page (indépendante de la première, qui peux aussi se redimentionner avec apparition de scrollbar ect...)


    je sais pas si c'est plus clair, en tout cas merci pour ton temps.

  14. #14
    Membre confirmé

    Homme Profil pro
    Bidouilleur
    Inscrit en
    Avril 2016
    Messages
    721
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Paris (Île de France)

    Informations professionnelles :
    Activité : Bidouilleur

    Informations forums :
    Inscription : Avril 2016
    Messages : 721
    Points : 503
    Points
    503
    Billets dans le blog
    1
    Par défaut
    Ah ok, j'avais pas saisi.

    Pour cela il suffisait d'ajouter :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    cadreA.grid_rowconfigure(0, weight=1)
    cadreA.grid_columnconfigure(0, weight=1)
    Même chose pour le cadre B

    Ainsi qu'un :
    Dans les grid CadreA, CadreB.
    Le temps ronge l'amour comme l'acide.

  15. #15
    Membre confirmé

    Homme Profil pro
    Bidouilleur
    Inscrit en
    Avril 2016
    Messages
    721
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Paris (Île de France)

    Informations professionnelles :
    Activité : Bidouilleur

    Informations forums :
    Inscription : Avril 2016
    Messages : 721
    Points : 503
    Points
    503
    Billets dans le blog
    1
    Par défaut
    Et en prime, parce que j'aime bien m'amuser un peu, une méthode pour justement ne garder qu'un seul cadre, au passage changement de la classe qui hérite de Canvas, il y a des avantages, car méthodes d'accès direct, mais l'inconvénient est qu'il faut utiliser Page.cadre comme parent des widgets enfants de la page.

    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
    #"""
    import tkinter as tk
     
    class AutoScrollbar(tk.Scrollbar):
        # a scrollbar that hides itself if it's not needed.  only
        # works if you use the grid geometry manager.
        def set(self, lo, hi):
            if float(lo) <= 0.0 and float(hi) >= 1.0:
                # grid_remove is currently missing from Tkinter!
                self.tk.call("grid", "remove", self)
            else:
                self.grid()
            tk.Scrollbar.set(self, lo, hi)
     
    class Page(tk.Canvas) :
        def __init__(self, parent, **dargs) :
            self._vscrollbar = AutoScrollbar(parent)
            self._vscrollbar.grid(row=0, column=1, sticky=tk.NS)
            self._hscrollbar = AutoScrollbar(parent, orient=tk.HORIZONTAL)
            self._hscrollbar.grid(row=1, column=0, sticky=tk.EW)
     
            df = dict(yscrollcommand=self._vscrollbar.set,
                      xscrollcommand=self._hscrollbar.set)
            super().__init__(parent, df, **dargs)
            self.grid(row=0, column=0, sticky=tk.NSEW)
     
            self._vscrollbar.config(command=self.yview)
            self._hscrollbar.config(command=self.xview)
     
            self.cadre = tk.Frame(self)
            self.cadre.bind('<Configure>', self._actualiserDimension)
     
            self.create_window(0, 0, anchor=tk.NW, window=self.cadre)
     
        def _actualiserDimension(self, evt=None) :
            self.config(scrollregion=self.bbox("all"))
     
    root = tk.Tk()
    root.geometry('{}x{}+{}+{}'.format(300, 300, 200, 200))
     
    root.grid_rowconfigure(0, weight=1)
    root.grid_columnconfigure(0, weight=1)
     
    page = Page(root)
     
    suivant = tk.Frame(page.cadre)
    suivant.grid(sticky=tk.NSEW)
    suivant.columnconfigure(0, weight=1)
     
    def pageSuivante() :
        for w in contenu.winfo_children() :
            try :
                w.destroy()
            except :
                continue
        bSuivant['text'] = int(bSuivant['text']) + 1
        ajouterContenu()
     
    bSuivant = tk.Button(suivant, text='2', command=pageSuivante)
    bSuivant.grid(sticky=tk.W)
     
    contenu = tk.Frame(page.cadre)
    contenu.grid()
     
    import random
     
    def ajouterContenu() :
        c = random.randint(5, 30)
        for i in range(random.randint(5, 30)) :
            for j in range(c) :
                l = tk.Label(contenu, padx=7, pady=7, text='L')
                l.grid(row=i, column=j, sticky='news')
     
    ajouterContenu()
     
    root.mainloop()
    #"""
    Le temps ronge l'amour comme l'acide.

  16. #16
    Membre habitué
    Homme Profil pro
    Étudiant
    Inscrit en
    Juillet 2016
    Messages
    132
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 26
    Localisation : France, Indre et Loire (Centre)

    Informations professionnelles :
    Activité : Étudiant
    Secteur : Industrie

    Informations forums :
    Inscription : Juillet 2016
    Messages : 132
    Points : 130
    Points
    130
    Par défaut
    Wow merci beaucoup c'est ce que j'attendais du programme.

    Juste une précision pour savoir si j'ai compris :
    Permettre de changer le "weight" de la colonne et de la ligne 1 donne de la place a la scrollbar c'est ça ?

    Encore merci pour ton aide et ton temps, désolé de n'avoir pas été clair des le début.

  17. #17
    Membre confirmé

    Homme Profil pro
    Bidouilleur
    Inscrit en
    Avril 2016
    Messages
    721
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Paris (Île de France)

    Informations professionnelles :
    Activité : Bidouilleur

    Informations forums :
    Inscription : Avril 2016
    Messages : 721
    Points : 503
    Points
    503
    Billets dans le blog
    1
    Par défaut
    Citation Envoyé par StabiloHB Voir le message
    Juste une précision pour savoir si j'ai compris :
    Permettre de changer le "weight" de la colonne et de la ligne 1 donne de la place a la scrollbar c'est ça ?.
    Cela indique ici à la frame d'occuper tout l'espace disponible.
    Mais plus généralement cela sert à effectuer la répartition des espaces à occuper par les widgets enfants dans le parent.
    Le temps ronge l'amour comme l'acide.

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

Discussions similaires

  1. Réponses: 2
    Dernier message: 19/05/2015, 08h52
  2. Scrollbar sur la Fenetre principale (Tkinter) ISN
    Par Displayed dans le forum Général Python
    Réponses: 1
    Dernier message: 09/09/2014, 13h22
  3. [Tkinter] Fenêtre avec scrollbar
    Par fire.stone dans le forum Tkinter
    Réponses: 2
    Dernier message: 31/08/2006, 22h01
  4. [tkinter] widget text et scrollbar
    Par jojolapine dans le forum Tkinter
    Réponses: 3
    Dernier message: 29/04/2006, 15h58
  5. [Tkinter] ScrollBar et méthode set
    Par BlackPearl dans le forum Tkinter
    Réponses: 1
    Dernier message: 02/04/2005, 20h06

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