Placement widget tkinter

Fermé
maxime_boris Messages postés 35 Date d'inscription dimanche 23 janvier 2022 Statut Membre Dernière intervention 17 novembre 2022 - 21 juil. 2022 à 15:55
 canard_cocasse - 24 juil. 2022 à 18:14

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

A voir également:

3 réponses

yg_be Messages postés 22727 Date d'inscription lundi 9 juin 2008 Statut Contributeur Dernière intervention 26 avril 2024 1 476
21 juil. 2022 à 16:03

bonjour,

et ainsi pour le 2ième?

can.create_rectangle(10,100,91,141)
0
Phil_1857 Messages postés 1883 Date d'inscription lundi 23 mars 2020 Statut Membre Dernière intervention 28 février 2024 178
Modifié le 21 juil. 2022 à 18:25

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
yg_be Messages postés 22727 Date d'inscription lundi 9 juin 2008 Statut Contributeur Dernière intervention 26 avril 2024 1 476
21 juil. 2022 à 19:08
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
maxime_boris Messages postés 35 Date d'inscription dimanche 23 janvier 2022 Statut Membre Dernière intervention 17 novembre 2022 > yg_be Messages postés 22727 Date d'inscription lundi 9 juin 2008 Statut Contributeur Dernière intervention 26 avril 2024
Modifié le 22 juil. 2022 à 23:33

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
yg_be Messages postés 22727 Date d'inscription lundi 9 juin 2008 Statut Contributeur Dernière intervention 26 avril 2024 1 476 > maxime_boris Messages postés 35 Date d'inscription dimanche 23 janvier 2022 Statut Membre Dernière intervention 17 novembre 2022
23 juil. 2022 à 08:23

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
canard_cocasse
24 juil. 2022 à 18:14

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