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 :

Forcer 2 frames à la même taille


Sujet :

Tkinter Python

Vue hybride

Message précédent Message précédent   Message suivant Message suivant
  1. #1
    Membre confirmé Avatar de sopsag
    Profil pro
    Inscrit en
    Octobre 2008
    Messages
    224
    Détails du profil
    Informations personnelles :
    Localisation : France, Paris (Île de France)

    Informations forums :
    Inscription : Octobre 2008
    Messages : 224
    Par défaut Forcer 2 frames à la même taille
    Bonjour,

    voici (encore) un petit problème pour les ceintures marrons de Tkinter :

    Je créé une petite GUI divisée en 4 frames (2x2).
    Chaque frame est en fait un "doublet de frames", une visible, l'autre invisible.
    Quand je clique sur une frame, elle devient invisible et c'est son double qui devient visible (ce sera plus facile à comprendre en testant le code).
    Jusqu'ici, ça marche impec'
    Le hic, c'est que la frame et son double n'ont pas la même taille est que du coup, l'appli se redimensionne toute seule selon les tailles respectives des frames visibles (il faut vraiment essayer pour visualiser...)

    --> ma question : comment faire pour que les 2 frames de chaque doublet aient la même taille ?
    Ou encore, comment éviter que l'appli se redimensionne ?
    --> un truc du genre : je créé les 2 frames de mon doublet, je calcule leur taille, puis je force la plus petite à la taille de la plus grande.

    Voici le 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
    import Tkinter
     
    def TestGUI () :
     
        # classe Cell = 2 frames superposees : 1 visible + 1 invisible
        class Cell:
     
            def __init__(self,x,y):
                self.visible  = 0           # indice de la frame visible
                self.frame    = [None,None] # les 2 frames superposees
                self.x,self.y = x,y         # coord de la frame
     
            def clic( self,event=None ):
                self.frame[self.visible].grid_forget() # rend la frame invisible
                self.visible = 1-self.visible          # inverse les visibilites des 2 frames
                self.frame[self.visible].grid( column=self.x,row=self.y, sticky=Tkinter.NSEW ) # rend la frame visible 
     
        grid  = [[ Cell(x,y) for x in xrange( 2 ) ] for y in xrange( 2 ) ]
        root  = Tkinter.Tk()
        frame = Tkinter.Frame( root )
        # cree 4 frames disposees en 2 x 2
        for y in xrange( 2 ):
            for x in xrange( 2 ):
                cell = grid[y][x]
     
                cell.frame[0] = Tkinter.Frame( frame,relief = Tkinter.SUNKEN , borderwidth = 4)
                txt = Tkinter.Label( cell.frame[0],text = 'very\nvery\nvery\nvery big\nand very very very large frame %d,%d'%(x,y))
                txt.pack( expand = 1 )              
                txt.bind('<Button-1>',cell.clic )
     
                cell.frame[1] = Tkinter.Frame( frame,relief = Tkinter.RAISED , borderwidth = 4)
                txt = Tkinter.Label( cell.frame[1],text = 'small frame %d,%d'%(x,y))
                txt.pack( expand = 1 )              
                txt.bind('<Button-1>',cell.clic )
     
                cell.clic()
        frame.pack() 
        root.mainloop()
     
    TestGUI()
    Merci d'avance !

  2. #2
    Membre très actif
    Avatar de afranck64
    Homme Profil pro
    Étudiant
    Inscrit en
    Janvier 2009
    Messages
    592
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 34
    Localisation : Cameroun

    Informations professionnelles :
    Activité : Étudiant
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Janvier 2009
    Messages : 592
    Par défaut
    Re bonjour,

    Pour avoir les dimensions de la grande Frame tu as Frame.cget("height") et Frame.cget("width") et pour configurer les dimensions de la petite Frame tu as Frame.configure(width=larg, height=haut).

    afranck64:future ceinture de Tkinter.

    a + et bon code.
    Win 10 64 bits / Linux Mint 18, - AMD A6 Quad: Py27 / Py35
    CONTENU D'UNE QUESTION
    Exemples:
    - Configuration (système d'exploitation, version de Python et des bibliothèques utilisées)
    - Code source du morceau de programme où il y a un bogue
    - Ligne de code sur laquelle le bogue apparaît
    - Erreur complète retournée pas l'interpréteur Python
    - Recherche déjà effectuée (FAQ, Tutoriels, ...)
    - Tests déjà effectués

  3. #3
    Membre confirmé Avatar de sopsag
    Profil pro
    Inscrit en
    Octobre 2008
    Messages
    224
    Détails du profil
    Informations personnelles :
    Localisation : France, Paris (Île de France)

    Informations forums :
    Inscription : Octobre 2008
    Messages : 224
    Par défaut
    merci de ta prompte réponse !
    mais heu... ça marche pas...

    les cget("height") et cget("width") renvoient toujours 0, quelque soit l'endroit d'où je les appelle (même à la toute fin de la construction, juste avant le mainloop()).

    configure(width=x, height=y) ne marche pas non plus, même avec des valeurs en dur, et même en appelant grid_propagate( False ) après.

    Voici ce que ça donne :
    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
    def TestGUI () :
     
        # classe Cell = 2 frames superposees : 1 visible + 1 invisible
        class Cell:
     
            def __init__(self,x,y):
                self.visible  = 0           # indice de la frame visible
                self.frame    = [None,None] # les 2 frames superposees
                self.x,self.y = x,y         # coord de la frame
     
            def clic( self,event=None ):
                self.frame[self.visible].grid_forget() # rend la frame invisible
                self.visible = 1-self.visible          # inverse les visibilites des 2 frames
                self.frame[self.visible].grid( column=self.x,row=self.y, sticky=Tkinter.NSEW ) # rend la frame visible 
     
        grid  = [[ Cell(x,y) for x in xrange( 2 ) ] for y in xrange( 2 ) ]
        root  = Tkinter.Tk()
        frame = Tkinter.Frame( root )
        root.bind('<Escape>',lambda e : root.quit())
        # cree 4 frames disposees en 2 x 2
        for y in xrange( 2 ):
            for x in xrange( 2 ):
                cell = grid[y][x]
     
                cell.frame[0] = Tkinter.Frame( frame,relief = Tkinter.SUNKEN , borderwidth = 4)
                txt = Tkinter.Label( cell.frame[0],text = 'very\nvery\nvery\nvery big\nand very very very large frame %d,%d'%(x,y))
                txt.pack( expand = 1 )              
                txt.bind('<Button-1>',cell.clic )
                cell.frame[0].grid( column=x,row=y,sticky=Tkinter.NSEW ) 
     
                cell.frame[1] = Tkinter.Frame( frame,relief = Tkinter.RAISED , borderwidth = 4)
                txt = Tkinter.Label( cell.frame[1],text = 'small frame %d,%d'%(x,y))
                txt.pack( expand = 1 )              
                txt.bind('<Button-1>',cell.clic )
                cell.frame[1].grid( column=x,row=y,sticky=Tkinter.NSEW ) 
     
                if 1: # pour pouvoir deconnecter ce code rapidement
                    sx = max( cell.frame[0].cget('width') ,cell.frame[1].cget('width'))
                    sy = max( cell.frame[0].cget('height'),cell.frame[1].cget('height'))
                    print 'cget --> %d,%d'%(sx,sy)
                    sx,sy = 250,250 # force les valeurs en dur
                    cell.frame[0].configure( width=sx , height=sy )
                    cell.frame[1].configure( width=sx , height=sy )
                    if 1 : # avec ou sans, ca ne marche pas...
                        cell.frame[0].grid_propagate( False )
                        cell.frame[1].grid_propagate( False )
     
                cell.clic()
        frame.pack()
        root.mainloop()
    Qu'est ce que j'ai raté ?

  4. #4
    Membre très actif
    Avatar de afranck64
    Homme Profil pro
    Étudiant
    Inscrit en
    Janvier 2009
    Messages
    592
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 34
    Localisation : Cameroun

    Informations professionnelles :
    Activité : Étudiant
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Janvier 2009
    Messages : 592
    Par défaut
    Bonjour,
    Je voudrais tout d'abord m excuser pour l'intox en fait avec le contenu des Frames que tu dois utiliser width et height. Dans ce cas c'est sur txt ainsi l'utilisateur ne sera forcé de cliquer sur le texte...

    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
    import Tkinter
    from Tkinter import *
     
     
    #params globaux
    width = 28
    height = 5
     
    def TestGUI () :
     
       # classe Cell = 2 frames superposees : 1 visible + 1 invisible
       class Cell:
     
           def __init__(self,x,y):
               self.visible  = 0           # indice de la frame visible
               self.frame    = [None,None] # les 2 frames superposees
               self.x,self.y = x,y         # coord de la frame
     
           def clic( self,event=None ):
               self.frame[self.visible].grid_forget() # rend la frame invisible
               self.visible = 1-self.visible          # inverse les visibilites des 2 frames
               self.frame[self.visible].grid( column=self.x,row=self.y,sticky=Tkinter.NSEW ) # rend la frame visible
     
       grid  = [[ Cell(x,y) for x in xrange( 2 ) ] for y in xrange( 2 ) ]
       root  = Tkinter.Tk()
       frame = Tkinter.Frame( root )
       root.bind('<Escape>',lambda e : root.quit())
       # cree 4 frames disposees en 2 x 2
       for y in xrange( 2 ):
           for x in xrange( 2 ):
               cell = grid[y][x]
     
               cell.frame[0] = Tkinter.LabelFrame( frame,relief =Tkinter.SUNKEN , borderwidth = 4)
               txt = Tkinter.Label( cell.frame[0],width=width,height=height,
                                    text ='very\nvery\nvery\nvery big\nand very very very large framed,%d'%(x))
               txt.pack( expand = 1 )
               txt.bind('<Button-1>',cell.clic )
               cell.frame[0].grid( column=x,row=y,sticky=Tkinter.NSEW )
     
               cell.frame[1] = Tkinter.LabelFrame( frame,relief =Tkinter.RAISED , borderwidth = 4)
               txt = Tkinter.Label( cell.frame[1],width=width,height=height,text = 'small frame %d,%d'%(x,y))
               txt.pack( expand = 1 )
               txt.bind('<Button-1>',cell.clic )
               cell.frame[1].grid( column=x,row=y,sticky=Tkinter.NSEW )
     
               """
               if 1: # pour pouvoir deconnecter ce code rapidement
                   sx = max( cell.frame[0].cget('width'),cell.frame[1].cget('width'))
                   sy = max(cell.frame[0].cget('height'),cell.frame[1].cget('height'))
                   print 'cget --> %d,%d'%(sx,sy)
                   sx,sy = 25,25 # force les valeurs en dur
                   cell.frame[0].configure( width=sx , height=sy )
                   cell.frame[1].configure( width=sx , height=sy )
                   if 1 : # avec ou sans, ca ne marche pas...
                       cell.frame[0].grid_propagate( False )
                       cell.frame[1].grid_propagate( False )
     
                
               """
               cell.clic()
       frame.pack()
       root.mainloop()
     
    TestGUI()
    @+ et bon code
    Win 10 64 bits / Linux Mint 18, - AMD A6 Quad: Py27 / Py35
    CONTENU D'UNE QUESTION
    Exemples:
    - Configuration (système d'exploitation, version de Python et des bibliothèques utilisées)
    - Code source du morceau de programme où il y a un bogue
    - Ligne de code sur laquelle le bogue apparaît
    - Erreur complète retournée pas l'interpréteur Python
    - Recherche déjà effectuée (FAQ, Tutoriels, ...)
    - Tests déjà effectués

  5. #5
    Membre confirmé Avatar de sopsag
    Profil pro
    Inscrit en
    Octobre 2008
    Messages
    224
    Détails du profil
    Informations personnelles :
    Localisation : France, Paris (Île de France)

    Informations forums :
    Inscription : Octobre 2008
    Messages : 224
    Par défaut
    Merci pour ces précisions.
    En effet, ça semble fonctionner, mais...

    malheureusement ça ne me convient pas parce que je ne connais pas à l'avance la taille de mes labels, et de plus, il n'y a pas forcement que des labels dans les frames.

    Voici mon exemple un peu étoffé avec le texte du label qui est un paramètre (du coup on ne peut pas prévoir sa taille) et une frame qui contient en plus un bouton.

    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
    def TestGUI ( message ) :
     
       # classe cellule = doublon de 2 frames superposees : 1 visible + 1 invisible
       class Cell:
     
           def __init__(self,x,y):
               self.visible  = 0           # indice de la frame visible
               self.frame    = [None,None] # les 2 frames superposees
               self.x,self.y = x,y         # coord de la frame
     
           def clic( self,event=None ):
               self.frame[self.visible].grid_forget() # rend la frame invisible
               self.visible = 1-self.visible          # inverse les visibilites des 2 frames
               self.frame[self.visible].grid( column=self.x,row=self.y,sticky=Tkinter.NSEW ) # rend la frame visible
     
       grid  = [[ Cell(x,y) for x in xrange( 2 ) ] for y in xrange( 2 ) ]
       root  = Tkinter.Tk()
       frame = Tkinter.Frame( root )
       root.bind('<Escape>',lambda e : root.quit())
       # cree 4 cellules disposees en 2 x 2
       for y in xrange( 2 ):
           for x in xrange( 2 ):
               # recupere la reference de la cellule x,y 
               cell = grid[y][x]
     
               # creation de la premiere frame
               cell.frame[0] = Tkinter.Frame( frame,relief =Tkinter.SUNKEN , borderwidth = 4)
               # ajout d'un label
               txt1 = Tkinter.Label( cell.frame[0],text ='very\nvery\nvery\nvery big\nand very very very large frame (%d,%d)'%(x,y))
               txt1.pack()
               # ajout d'un bouton
               but1 = Tkinter.Button( cell.frame[0],anchor = Tkinter.CENTER,text = 'Hide',command = cell.clic )
               but1.pack()
               cell.frame[0].grid( column=x,row=y,sticky=Tkinter.NSEW )
     
               # creation de la seconde frame
               cell.frame[1] = Tkinter.Frame( frame,relief =Tkinter.RAISED , borderwidth = 4)
               txt2 = Tkinter.Label( cell.frame[1],text = message+' (%d,%d)'%(x,y))
               txt2.pack( expand = 1 )
               txt2.bind('<Button-1>',cell.clic )
               cell.frame[1].grid( column=x,row=y,sticky=Tkinter.NSEW )
     
               cell.clic()
       frame.pack()
       root.mainloop()
       root.destroy()
     
    TestGUI('Hello')
    TestGUI('il etait une fois un marchand de foie qui vendait du foie\ndans la ville de Foix.\nIl se dit "ma foi\nc\'est bien la premiere fois\net la derniere fois\nque je vends du foie\ndans la ville de Foix".\n...\n')
    Du coup, je pense qu'il faut bien demander à la frame sa taille pour pouvoir forcer la taille de l'autre, mais je ne vois toujours pas comment faire...
    Les cget('width') renvoient toujours 0.

  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
    Bonjour sopsag,

    Pour avoir la géométrie tu dois faire un update de ta Frame.

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
               cell.frame[0].grid( column=x,row=y,sticky=Tkinter.NSEW )
               cell.frame[0].update()
               print cell.frame[0].winfo_reqheight(), cell.frame[0].winfo_reqwidth()
    Bon code

    Edit : Comme j'ai deux minutes...
    La Frame Tkinter a une géométrie de 0x0 à sa création et reste ainsi pour la Wrapper. C'est la Frame Tk qui se redimensionne a son contenu.
    Pour récupérer dans le dico de ton Widget les info tu dois utiliser .update()
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
        def update(self):
            """Enter event loop until all pending events have been processed by Tcl."""
            self.tk.call('update')
    Note : un .destroy() après le .mainloop() ?

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

Discussions similaires

  1. Avoir pour toutes les images la même taille
    Par namstou3 dans le forum ActionScript 1 & ActionScript 2
    Réponses: 1
    Dernier message: 13/12/2007, 15h35
  2. charger deux frame en même temps
    Par ivanoe25 dans le forum Général JavaScript
    Réponses: 4
    Dernier message: 17/11/2006, 15h41
  3. même taille après DELETE !
    Par Ickou dans le forum Requêtes
    Réponses: 2
    Dernier message: 29/05/2006, 17h14
  4. menu et contenu de même taille
    Par furth dans le forum Balisage (X)HTML et validation W3C
    Réponses: 5
    Dernier message: 27/05/2006, 10h16
  5. Réponses: 4
    Dernier message: 14/06/2004, 09h29

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