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 :

Utilisation de columnconfigure


Sujet :

Tkinter Python

  1. #1
    Candidat au Club
    Homme Profil pro
    Aide-soignant
    Inscrit en
    Novembre 2011
    Messages
    2
    Détails du profil
    Informations personnelles :
    Sexe : Homme

    Informations professionnelles :
    Activité : Aide-soignant
    Secteur : Santé

    Informations forums :
    Inscription : Novembre 2011
    Messages : 2
    Points : 4
    Points
    4
    Par défaut Utilisation de columnconfigure
    Bonjour,

    C'est un peu la question de la honte, mais bon...

    Je ne comprends pas le principe de l'utilisation de l'option weight de la méthode columnconfigure dans le cas où l'on veut forcer l'espace relatif de chaque colonne dans un Frame par exemple.

    J'ai trouvé de la doc qui est en fait la traduction de ce lien : http://infohost.nmt.edu/tcc/help/pubs/tkinter.pdf

    Il y est dit :
    Pour faire une colonne ou une rangée étirable, utilisez cette option et fournissez
    une valeur qui donne le poids relatif de cette colonne ou rangée en distribuant l'espace supplémentaire. Par exemple, si un widget w contient une configuration de grille, ces lignes distribueront 3/4 de l'espace supplémentaire à la première colonne et 1/4 à la deuxième colonne :
    w.columnconfigure(0, weight=3)
    w.columnconfigure(1, weight=1)
    Eventuellement je peux comprendre que l'on divise le frame en 4 "morceaux", on en affecte 3 à la première colonne et 1 à la dernière.

    Mais dans le cas où l'on veut trois colonnes égales? On divise en 3 et on affecte 1 à chaque colonne? J'ai essayé, cela ne marche pas. J'obtiens des zones étirables, mais pas de largeur égale.
    La finalité est pour avoir trois boutons dans un frame qui on la même largeur quelque soit ce qui est au dessus et qui détermine la largeur de la fenêtre de l'application.

    Voici le code de l'appli. J'ai juste laissé les classe qui permettent l'affichage.
    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
    #-*- coding : utf8 -*-
     
    #importation de fonctions externes
    from tkinter import * #importation du module graphique tkinter sous python 3. /!\ a ne pas confondre avec Tkinter avec python 2
    import time#importation module time pour la mesure du tps
     
    #import re#importation du module re pour travailler avec les expression régulière
     
     
    # *** DEFINITION LOCAL DE CLASSE
    class LabelRb(Label):#on fait hériter cette classe de la classe Label
      """
      classe pr créer des label identique d'aspect
      """
      def __init__(self, parent, contenu, lig, col):#methode constructeur
        Label.__init__(self, parent)#on appel le constructeur de la classe Label
        self.grid(row=lig, column=col)
        self.configure(text=contenu, bg="#EED8AE", fg="blue")
     
     
    class EntryRb(Entry):#on fait hériter cette classe de la classe Entry
      """
      classe pour crée des Entry identique d'aspect et de propriété notament pr le clic de souris
      """
     
      def __init__(self, parent, contenu,lig, col):#methode constructeur
        #print(parent.geometry)
        Entry.__init__(self, parent)#on appel le constructeur de la classe Entry à qui on affecte l'objet crée ds nouvelle classe issue de l'héritage. On obtient un Entry que l'on peut adapter à nos besoins.
        self.grid(row=lig, column=col, sticky=E+W)#on applique la méthode de positionnement grid() à self. Ceci possible car self et par défaut un Entry
        self.config(width="7")
        self.insert(0, contenu)#on insert par défaut la valeur 0 ds tous les Entry instancié.
        self.bind("<Button-1>", lambda event=None: self.deleteEntry())#au clic gauche, on appel la méthode deleteEntry qui met à vide l'Entry.
        #print(self.master.winfo_height)
        #print("qqc")
     
      def deleteEntry(self):#méthode qui vide l'entry. On donne en argument self, bien qu'à l'appel de la méthode on n'en donne pas.
        self.delete(0,END)#on efface le contenu de l'Entry du début (indice 0), jusqu'au dernier indice (END, END permet de connaitre cet indice ss calcul)
     
     
    class ButtonRb(Button):
      """
      classe pr créer des Button identique d'aspect
      """
      def __init__(self, parent, contenu, lig, col):#methode constructeur.
        #parent=le contenant parent, contenu=le label du bouton, lig et col=position du widget avec grid(), action=commad à executer par button
        Button.__init__(self, parent)#on appel le constructeur de la classe Button
        self.config(text=contenu, bg="#EED8AE", fg="blue")#ligne qui permet d'ajouter des attribut à l'objet
        self.grid(row=lig, column=col, sticky=E+W, ipadx=0, ipady=0)#on applique la méthode de positionnement grid() à self.
     
     
    fenPrin=Tk()
    fenPrin.title("Compte à rebours")
    fenPrin.configure(bg="#EED8AE")
     
    #LIGNE 0
    entIntitule=EntryRb(fenPrin, "Titre du compte à rebours", "0", "0")
     
     
    #LIGNE 1
    #FRAME frmTps . Frame contenant les widget relatif au temps
    frmTps=Frame(fenPrin, bg="#EED8AE")
    frmTps.grid(row="1", column="0")
     
    #--frmTps LIGNE 0
    lblHeure=LabelRb(frmTps, "Heure", "0", "0")#instanciation des Label
    lblMin=LabelRb(frmTps, "Minute", "0", "1")
    lblSec=LabelRb(frmTps, "Seconde", "0", "2")
    lblTitreDec=LabelRb(frmTps, "Temps restant", "0", "3")
     
    #--frmTps LIGNE 1
    entHeure=EntryRb(frmTps, "0", "1", "0")#instanciation des Entry
    entMin=EntryRb(frmTps, "0", "1", "1")
    entSec=EntryRb(frmTps, "0", "1", "2")
    lblAffDec=LabelRb(frmTps, "00 00 00", "1", "3")#Label d'affichage du décompte
     
     
    #LIGNE 2
    #FRAME frmBt. Frame contenant les boutons
    frmBt=Frame(fenPrin, bg="#EED8AE")
    frmBt.grid(row="2", column="0", sticky=E+W)
    frmBt.columnconfigure(0, weight=3)
    frmBt.columnconfigure(1, weight=3)
    frmBt.columnconfigure(2, weight=0)
     
    #création de la liste contenant les Entry des H M N
    lstTps=list()#instantiation de la liste
    lstTps=[entHeure, entMin, entSec]
     
     
    #--frmBt LIGNE 0
    btArret=ButtonRb(frmBt, "Quitter", "0","0")
    btStart=ButtonRb(frmBt, "Départ", "0","1")
    btReset=ButtonRb(frmBt, "Mise à zéro", "0","2")
     
     
    fenPrin.mainloop()#la fenêtre principale est en attente d'action
    La partie qui utilise columnconfigure est :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    #LIGNE 2
    #FRAME frmBt. Frame contenant les boutons
    frmBt=Frame(fenPrin, bg="#EED8AE")
    frmBt.grid(row="2", column="0", sticky=E+W)
    frmBt.columnconfigure(0, weight=3)
    frmBt.columnconfigure(1, weight=3)
    frmBt.columnconfigure(2, weight=0)

  2. #2
    Membre éprouvé
    Homme Profil pro
    Aucune activité
    Inscrit en
    Novembre 2011
    Messages
    505
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations professionnelles :
    Activité : Aucune activité

    Informations forums :
    Inscription : Novembre 2011
    Messages : 505
    Points : 926
    Points
    926
    Par défaut
    Coucou,
    De ce que j'en sais, ces options servent uniquement lors du redimensionnement de la fenêtre.
    Et surtout, les columnconfigure et rowconfigure s'appliquent au widget contenant le grid.
    De plus, si le widget est dans un ancêtre, ce dernier doit aussi être configuré… (De même que les autres éléments descendant de ce parent).
    Ce n'est, AHMA, vraiment pas facile à utiliser!

    Un petit exemple (il faut agrandir l'ensemble pour voir le résultat):
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
     
    from tkinter import *
    fen=Tk()
    can1=Canvas(fen, bg="red", width=100, height=100)
    can1.grid(row=1,column=1,sticky="NSWE")
    can2=Canvas(fen, bg="blue", width=100, height=100)
    can2.grid(row=1,column=2,sticky="NSWE")
    fen.columnconfigure(1,weight=1)
    fen.columnconfigure(2,weight=5)
    fen.rowconfigure(1,weight=1)
    fen.mainloop()
    Voilà… Après je ne suis pas spécialiste!

  3. #3
    Expert confirmé 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
    Points : 4 005
    Points
    4 005
    Par défaut
    Bonjour,

    En fait weight est une priorité a utiliser l'espace libre. Plus le chiffre est grand et plus la colonne/ligne est prioritaire, 0 pas de priorité.
    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
    from tkinter import *
     
    root = Tk()
    root.geometry("1000x200")
     
    frm0 = Frame(root)
    Label(frm0, bg='blue').grid(row=0, column=0, sticky=E+W)
    Label(frm0, bg='red').grid(row=0, column=1, sticky=E+W)
    Label(frm0, bg='green').grid(row=0, column=2, sticky=E+W)
    frm0.grid(row=0, column=0, sticky=E+W)
    frm0.columnconfigure(0, weight=0)
    frm0.columnconfigure(1, weight=2)
    frm0.columnconfigure(2, weight=1)
    #
    frm1 = Frame(root)
    Button(frm1, text='Un').grid(row=0, column=0, sticky=E+W)
    Button(frm1, text='Voici le deuxième').grid(row=0, column=1, sticky=E+W)
    Button(frm1, text='Et un texte un tantinet plus long').grid(row=0, column=2, sticky=E+W)
    frm1.grid(row=1, column=0, sticky=E+W)
    root.update()
    reqw = root.winfo_width()/3
    frm1.columnconfigure(0, minsize=reqw)
    frm1.columnconfigure(1, minsize=reqw)
    frm1.columnconfigure(2, minsize=reqw)
    #
    def getsize(widget, reqw=0, reqh=0):
        widget.update()
        if widget.winfo_reqwidth() > reqw:
            reqw = widget.winfo_reqwidth()
        if widget.winfo_reqheight() > reqh:
            reqh = widget.winfo_reqheight()
        return reqw, reqh
     
    frm2 = Frame(root)
    b1 = Button(frm2, text='Un\ndeux\ntrois\nquatre')
    b1.grid(row=0, column=0, sticky=E+W)
    reqw, reqh = getsize(b1)
    b2 = Button(frm2, text='Voici un autre Widget')
    b2.grid(row=0, column=1, sticky=E+W)
    reqw, reqh = getsize(b2)
    b3 = Button(frm2, text='Et un texte un tantinet plus long')
    b3.grid(row=0, column=2, sticky=E+W)
    reqw, reqh = getsize(b3)
    frm2.grid(row=2, column=0, sticky=E+W)
    frm2.columnconfigure(0, minsize=reqw)
    frm2.columnconfigure(1, minsize=reqw)
    frm2.columnconfigure(2, minsize=reqw)
    frm2.grid_rowconfigure(0, minsize=reqh)
    root.mainloop()
    Vous remarquerez que la colonne du label rouge avec son 'poids' de 2 utilise plus d'espace que celle du vert (weight=1) et que celle du bleu avec son weight=0 en est réduit au minimum.
    Pour les boutons vous avez deux exemples: Un sur la taille du conteneur et l'autre sur le contenu.
    A noter: Si vous utilisez un Widget Frame il est nécessaire de faire un .update() sinon celui ci vous retourne une taille de 0.

    Pour ce qui est de la question (3 zones égales):
    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
    from tkinter import *
     
    root = Tk()
     
    frm = Frame(root)
    b1 = Button(frm, text='Un')
    b1.grid(row=0, column=0, sticky=E+W)
    b2 = Button(frm, text='Deux')
    b2.grid(row=0, column=1, sticky=E+W)
    b3 = Button(frm, text='Et un texte un tantinet plus long')
    b3.grid(row=0, column=2, sticky=E+W)
    reqw = 0
    for widget in frm.grid_slaves(): # Retourne les Widgets enfants par rapport à grid.
    #for widget in frm.winfo_children(): # Retourne les Widgets enfants.
        if widget.winfo_reqwidth() > reqw:
            reqw = widget.winfo_reqwidth()
    frm.grid(sticky=E+W)
    #frm.columnconfigure(0, minsize=reqw)
    #frm.columnconfigure(1, minsize=reqw)
    #frm.columnconfigure(2, minsize=reqw)
    for r in range(frm.grid_size()[0]):
        frm.columnconfigure(r, minsize=reqw)
    root.mainloop()
    @+

  4. #4
    Membre éprouvé
    Homme Profil pro
    Aucune activité
    Inscrit en
    Novembre 2011
    Messages
    505
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations professionnelles :
    Activité : Aucune activité

    Informations forums :
    Inscription : Novembre 2011
    Messages : 505
    Points : 926
    Points
    926
    Par défaut
    Mais dans le cas où l'on veut trois colonnes égales? On divise en 3 et on affecte 1 à chaque colonne? J'ai essayé, cela ne marche pas. J'obtiens des zones étirables, mais pas de largeur égale.
    Il me semble que pour que les zones soient étirables et de largeur égale, il faut quand même ajouter les poids (ainsi qu'à la racine, sinon rien ne s'étend):
    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
     
    from tkinter import *
     
    root = Tk()
     
    frm = Frame(root)
    b1 = Button(frm, text='Un')
    b1.grid(row=0, column=0, sticky=E+W)
    b2 = Button(frm, text='Deux')
    b2.grid(row=0, column=1, sticky=E+W)
    b3 = Button(frm, text='Et un texte un tantinet plus long')
    b3.grid(row=0, column=2, sticky=E+W)
    reqw = 0
    for widget in frm.grid_slaves(): # Retourne les Widgets enfants par rapport à grid.
        if widget.winfo_reqwidth() > reqw:
            reqw = widget.winfo_reqwidth()
    frm.grid(sticky=E+W)
    for r in range(frm.grid_size()[0]):
        frm.columnconfigure(r, minsize=reqw, weight=1)
    frm.master.columnconfigure(0, weight=1) # pour que la Frame puisse être agrandie
    root.mainloop()
    Non? Je fais une erreur quelque part?

  5. #5
    Expert confirmé 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
    Points : 4 005
    Points
    4 005
    Par défaut
    Exact. Je me suis juste basé sur la demande: Ajuster le parent par rapport au contenu.

  6. #6
    Candidat au Club
    Homme Profil pro
    Aide-soignant
    Inscrit en
    Novembre 2011
    Messages
    2
    Détails du profil
    Informations personnelles :
    Sexe : Homme

    Informations professionnelles :
    Activité : Aide-soignant
    Secteur : Santé

    Informations forums :
    Inscription : Novembre 2011
    Messages : 2
    Points : 4
    Points
    4
    Par défaut
    Bonjour PauseKawa et Clodion,

    Un gros merci pour commencer.
    J'ai effectivement la réponse à ma question et j'ai bien compris.

    Je salue la qualité de vos réponses qui constitue un véritable tutorial.

    Bien à vous.

    Stéphane

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

Discussions similaires

  1. utiliser les tag [MFC] [Win32] [.NET] [C++/CLI]
    Par hiko-seijuro dans le forum Visual C++
    Réponses: 8
    Dernier message: 08/06/2005, 15h57
  2. Réponses: 4
    Dernier message: 05/06/2002, 14h35
  3. utilisation du meta type ANY
    Par Anonymous dans le forum CORBA
    Réponses: 1
    Dernier message: 15/04/2002, 12h36
  4. [BCB5] Utilisation des Ressources (.res)
    Par Vince78 dans le forum C++Builder
    Réponses: 2
    Dernier message: 04/04/2002, 16h01
  5. Réponses: 2
    Dernier message: 20/03/2002, 23h01

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