Placement widget tkinter

maxime_boris Messages postés 39 Statut Membre -  
 canard_cocasse -

Bonjour, je voudrais placer 20 Canvas rectangle dans mon programme en les plaçant par 5 sur une ligne, Je n'arrive pas a placer correctement les widgets au bon endroit surtout pour placer les 5 widgets sur la deuxième ranger. le rectangle de la deuxième rangée et collé avec la première.

voici mon programme:

from tkinter import *


f = Tk()
f.title("SAMARITAIN")
f.geometry("700x700")

can = Canvas(width= 550, height =600, bg ="green")
can.pack()
can.create_rectangle(10,50,91,91, fill='white')
can.create_rectangle(111,50,186,91,fill='white')
can.create_rectangle(205,50,285,91,fill='white')
can.create_rectangle(303,50,390,91,fill='white')
can.create_rectangle(410,50,500,91,fill='white')
can.create_rectangle(10,101,114,91)
f.mainloop()

pourriez-vous m'aider à résoudre ce problème svp.
Windows / Chrome 103.0.0.0

3 réponses

  1. yg_be Messages postés 23437 Date d'inscription   Statut Contributeur Dernière intervention   Ambassadeur 1 588
     

    bonjour,

    et ainsi pour le 2ième?

    can.create_rectangle(10,100,91,141)
    0
  2. Phil_1857 Messages postés 1883 Date d'inscription   Statut Membre Dernière intervention   169
     

    Bonjour,

    au lieu d'écrire 20 fois can.create_rectangle(), pourquoi ne ferais-tu pas 2 boucles imbriquées

    la 1ere de 0 à 4 pour les lignes, la 2eme de 0 à 5 pour les colonnes

    et dans la boucle, tu calcules les coordonnées du rectangle en fonction des x et y de départ (10,50)

    de la distance entre 2 rectangles et de la hauteur et largeur d'un rectangle

    for lignes in range(4):
        for colonnes in range(5):
            #ici : calcul de x et y
            can.create_rectangle(x, y, x+largeur, y+hauteur, fill='white')
    
        #ici : y de départ =  y de départ + distance en hauteur dessiner pour la ligne suivante
    
    0
    1. yg_be Messages postés 23437 Date d'inscription   Statut Contributeur Dernière intervention   1 588
       
      x1,y1=40,50
      r1,r2=80,40
      d1,d2=20,40
      for j in range(4):
          for i in range(5):
              x,y=x1+i*(r1+d1),y1+j*(r2+d2)
              can.create_rectangle(x,y,x+r1,y+r2, fill='white')
      0
      1. maxime_boris Messages postés 39 Statut Membre > yg_be Messages postés 23437 Date d'inscription   Statut Contributeur Dernière intervention  
         

        Bonsoir yb_be, ton code fonctionne parfaitement, pourrais tu m'expliquer en détail le mécanisme de ton code s'il te plait car je n'y comprend rien surtout les variables(coordonnées du widgets) .

         Je souhaite ajouter des étiquettes (numéros) au dessus de chaque widgets et je voudrais également  écrire a l'intérieur  avec la fonction create_text() des nombres flottants mais je ne suis pas encore doué pour déterminé les coordonnées de chaque variables.

        Merci.

        0
      2. yg_be Messages postés 23437 Date d'inscription   Statut Contributeur Dernière intervention   1 588 > maxime_boris Messages postés 39 Statut Membre
         

        J'ai ajouté des commentaires, et un print().  Examine le résultat du print().

        from tkinter import *
        f = Tk()
        f.title("SAMARITAIN")
        f.geometry("700x700")
        can = Canvas(width= 550, height =600, bg ="green")
        can.pack()
        x1,y1=40,50   # position du premier rectangle
        r1,r2=80,40   # dimension des rectangles
        d1,d2=20,40   # espaces horizontal et vertical entre deux rectangles
        for j in range(4):
            for i in range(5):
                x,y=x1+i*(r1+d1),y1+j*(r2+d2)
                print("Position du rectangle en ligne {}, colonne {}:{}".format(i+1,j+1,(x,y)))
                can.create_rectangle(x,y,x+r1,y+r2, fill='white')
        f.mainloop()
        
        0
  3. canard_cocasse
     

    Bonjour, en ajoutant les étiquettes à tes rectangles.

    import tkinter as tk
    import random
    
    RECT_WIDTH, RECT_HEIGHT = 80, 95
    START_X, START_Y = 40, 50
    MARGIN_HORIZONTAL, MARGIN_VERTICAL = 20, 40
    
    # Création de nombres au hasard afin d'avoir du contenu pour peupler les rectangles
    numbers = [
        [round(random.uniform(0, 100), 3) for _ in range(random.randrange(1, 4))]
        for __ in range(20)
    ]
    
    
    def label_create(canvas, x, y, text):
        # Crée les étiquettes de 50 x 15
        coord = x + 10, y - 15, x + RECT_WIDTH - 20, y
        canvas.create_rectangle(*coord, fill='#aaa', outline='white', width=3)
        canvas.create_text(coord[0] + 25, coord[1] + 7, text=text, fill='green')
    
    
    def content_create(canvas, x, y, numbers, color='#333'):
        x += RECT_WIDTH - 10
        y += 15
        for n in numbers:
            canvas.create_text(x, y, font=('', 8), text=n, fill=color, anchor=tk.NE)
            y += 10
    
    
    window = tk.Tk()
    window.title('SAMARITAIN')
    
    can = tk.Canvas(window, width=550, height=600, bg='green')
    can.pack()
    
    for i in range(20):
        # Rappel le % vaut le reste et le // le quotient de la division entière
        x = START_X + (RECT_WIDTH + MARGIN_HORIZONTAL) * (i % 5)
        y = START_Y + (RECT_HEIGHT + MARGIN_VERTICAL) * (i // 5)
        iid = can.create_rectangle(
            x, y, x + RECT_WIDTH, y + RECT_HEIGHT, fill='white', outline='white'
        )
        label_create(can, x, y, f'n°{i + 1}')
        content_create(can, x, y, numbers[i])
        # print(f'tour {i}: coord rect. = {can.coords(iid)}')
    
    window.mainloop()

    Une autre solution serait de ne plus utiliser de canvas, mais d'autres widgets tkinter, exemple avec labelframe et label.

    import tkinter as tk
    import random
    
    numbers = [
        [round(random.uniform(0, 100), 3) for _ in range(random.randrange(1, 4))]
        for __ in range(20)
    ]
    
    window = tk.Tk()
    window.geometry('600x650')
    window.columnconfigure(0, weight=1)
    window.rowconfigure(0, weight=1)
    
    global_frame = tk.Frame(window, bg='green', padx=25, pady=25)
    global_frame.grid(sticky=tk.NSEW)
    
    # Permet de compartimenter uniformément la frame hor. et vert.
    for i in range(5):
        global_frame.columnconfigure(i, weight=1)
    for i in range(4):
        global_frame.rowconfigure(i, weight=1)
    
    for i in range(20):
        lbl_frame = tk.LabelFrame(
            global_frame, text=f'n°{i + 1}', bg='white', fg='#333'
        )
        lbl_frame.grid(row=i % 4, column=i // 4, sticky=tk.NSEW, padx=10, pady=10)
        lbl_frame.columnconfigure(0, weight=1)
        lbl_frame.rowconfigure(0, weight=1)
        content = tk.Label(
            lbl_frame,
            bg='white',
            fg='#333',
            anchor=tk.NE,
            padx=10,
            pady=15,
            text='\n'.join(str(n) for n in numbers[i]),
        )
        # Le sticky permet d'étirer le label au dimension du labelframe
        content.grid(sticky=tk.NSEW)
    
    window.mainloop()

    Les labelframes disposent de peu d'options d'agrémentations au regard d'un canvas, toutefois il est possible d'utiliser un label pour l'étiquette.

    L'avantage par rapport au canvas est que tout est redimensionnable automatiquement en agrandissant réduisant la fenêtre, ce qui est tout de même appréciable.

    0