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 :

Problème temps de latence


Sujet :

Tkinter Python

Vue hybride

Message précédent Message précédent   Message suivant Message suivant
  1. #1
    Membre éprouvé
    Profil pro
    Inscrit en
    Février 2003
    Messages
    926
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Février 2003
    Messages : 926
    Par défaut Problème temps de latence
    Bonjour,

    j'ai une grille et quand je clique sur une case de cette grille, ça supprime la ligne et la colonne qui la contiennent.
    Le problème c'est que c'est quasi instantanné pour une grille de 20 X 20 cases, et que ça prend 3 à 4 secondes pour une grille de 50 X 50 cases.
    Pour modifier la taille de la grille dans le code ci-dessous, il suffit de modifier la valeur du paramètre longueurGrille :

    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
    #!/usr/bin/env python3
    # -*- coding: utf-8 -*-
     
    from tkinter import *
     
    # on crée la fenêtre principale
    fenetre = Tk()
     
    def delete(event,arg1,arg2):
        #print(canvas.grid_slaves(row, column))
        for canvas in fenetre.grid_slaves():
          if int(canvas.grid_info()["row"]) == arg1:
            canvas.grid_forget()
        for canvas in fenetre.grid_slaves():
          if int(canvas.grid_info()["column"]) == arg2:
            canvas.grid_forget() 
     
    longueurGrille=50
    n=1    
    j = 1
    while j < longueurGrille:
        i=1
        while i < longueurGrille:
            canvas = "canvas" + str(i) + str(j)
            canvas = Canvas(fenetre, bg="pale goldenrod")
            canvas.grid(row=j, column=i, sticky=NW+SE)
            if i == 5:
                label = Label(canvas, bg="white", text=n, width=4, height=1, borderwidth=2, relief="solid")
                label.bind("<Button-1>", lambda event, arg1=j, arg2=i: delete(event, arg1, arg2))
            else:
                label = Label(canvas, bg="white", text=n, width=4, height=1, borderwidth=2, relief="solid")
                label.bind("<Button-1>", lambda event, arg1=j, arg2=i: delete(event, arg1, arg2))
            label.grid(row=j, column=i, sticky=NW+SE)        
            i=i+1
            n=n+1
        j=j+1
     
    # on lance la boucle principale
    fenetre.mainloop()
    Pourriez-vous m'aider à résoudre ce problème svp?

    Merci d'avance, cordialement,
    Arsène

  2. #2
    Membre très actif

    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
    Billets dans le blog
    1
    Par défaut
    Salut.

    Je n'ai pas autant de latence que toi, mais tu as quand même beaucoup de widgets, 250 canevas, 250 labels avec 250 events

    Je ne sais pas quel est ton but final de faire cela, mais en gérant le tout avec un unique canevas et des rectangles ce serait sans doute mieux, enfin faudrait tester, et voir ce que ça donne niveau perfs, je pense qu'utiliser les tags du rectangle pour y stocker sa ligne et colonne pourrait être intéressant.

    Ah oui en effet, c'est 2500 de chaque, pas 250...

  3. #3
    Expert confirmé

    Homme Profil pro
    Inscrit en
    Octobre 2008
    Messages
    4 307
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : Belgique

    Informations forums :
    Inscription : Octobre 2008
    Messages : 4 307
    Par défaut
    Salut,

    Tout d'abord, si on lit bien ton code, tu construis 2500 canvas, pourquoi donc ?

    Ensuite si tu fais un print(canvas.grid_info()["row"]) tu verras que cela te retourne toujours le total de rows, ça ne peut donc pas servir à ce que tu veux faire.

    Et aussi, tu comptes tes lignes et colonnes en commençant par 1, il faut commencer par zéro.

  4. #4
    Membre éprouvé
    Profil pro
    Inscrit en
    Février 2003
    Messages
    926
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Février 2003
    Messages : 926
    Par défaut
    Merci de vos réponses.

    si j'ai construit autant de canvas et de labels c'est parce que je voulais avoir une grille avec des cases comportant une inscription à l'intérieur. J'ai supprimé tous les labels et ça n'a pas changé le résultat. Quand y'a 50 canvas et qu'on veut supprimer une ligne ou une colonne, ça demande un certain temps et j'ai besoin d'une réponse immédiate pour que le jeu que je suis en train de faire soit jouable. J'espère qu'avec les rectangle ça sera instantané. Quand j'aurai réglé ce dernier problème, je testerai probablement pygame.

    En tous cas, si je fais un print(canvas.grid_info()["row"]) dans ma fonction delete(),

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    def delete(event,arg1,arg2):
        #print(canvas.grid_slaves(row, column))
        for canvas in fenetre.grid_slaves():
          print(int(canvas.grid_info()["row"]))
    j'obtiens bien le rang de chaque canvas et non pas le nombre total de rows à chaque fois. Pour le i et j, je suis d'accord, il faut bien partir de 0.

  5. #5
    Expert éminent
    Homme Profil pro
    Architecte technique retraité
    Inscrit en
    Juin 2008
    Messages
    21 741
    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 741
    Par défaut
    Citation Envoyé par Arsene12 Voir le message
    J'espère qu'avec les rectangle ça sera instantané. Quand j'aurai réglé ce dernier problème, je testerai probablement pygame.
    Avec une complexité en O(n²), il ne faut pas espérer, il faut avoir de bons algos.

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

  6. #6
    Membre très actif

    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
    Billets dans le blog
    1
    Par défaut
    Un exemple avec un unique canevas et des rectangles, et en servant des tags pour y enregistrer les index de la ligne et colonne.

    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
    import tkinter as tk
     
    DIM_GRILLE = (50, 50)
    DIM_CASE = 10
    DIM_LIGNE = 1
     
    DIM_CANEVAS = (
        DIM_GRILLE[0]*DIM_CASE + (DIM_GRILLE[0]+1)*DIM_LIGNE,
        DIM_GRILLE[1]*DIM_CASE + (DIM_GRILLE[1]+1)*DIM_LIGNE
    )
     
     
    def delete(evt) :
        r = can.find_overlapping(evt.x, evt.y, evt.x, evt.y)
        if not r :
            return
        ligne, colonne = can.gettags(r[0])[:2]
        iligne, icolonne = int(ligne[1:]), int(colonne[1:])
     
        for i in range(iligne+1, DIM_GRILLE[1]+1) :
            can.move('l'+str(i), 0, -(DIM_CASE+DIM_LIGNE))
     
        for i in range(icolonne+1, DIM_GRILLE[0]+1) :
            can.move('c'+str(i), -(DIM_CASE+DIM_LIGNE), 0)
     
        can.delete(ligne)
        can.delete(colonne)
     
     
    fenetre = tk.Tk()
     
    can = tk.Canvas(
        fenetre,
        width=DIM_CANEVAS[0],
        height=DIM_CANEVAS[1],
        bg='black',
        highlightthickness=0,
    )
    can.grid()
     
    items = []
    colors = ['red', 'yellow']
    y = DIM_LIGNE
     
    for ligne in range(DIM_GRILLE[1]) :
        x = DIM_LIGNE
        ids = []
        colors.reverse()
        for col in range(DIM_GRILLE[0]) :
            i = can.create_rectangle(
                x, y, x+DIM_CASE, y+DIM_CASE,
                fill=colors[col%2],
                width=0,
                tags='l{} c{}'.format(ligne, col),
            )
            ids.append(i)
            x += DIM_CASE + DIM_LIGNE
        items.append(ids)
        y += DIM_CASE + DIM_LIGNE
     
    can.bind('<Button-1>', delete)
     
    fenetre.mainloop()
    C'est déjà bien plus réactif.
    Reste à voir si cela peut te convenir.

    J'ai enregistré les ids des items, à toi aussi de voir si tu en as réellement besoin.

  7. #7
    Membre éprouvé
    Profil pro
    Inscrit en
    Février 2003
    Messages
    926
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Février 2003
    Messages : 926
    Par défaut
    Merci beaucoup, c'est vraiment top. Je vous félicite. Le code est court et je pouvais rêver mieux. Par contre il va falloir que je m'attelle à bien le comprendre, ligne par ligne. Si j'arrive ensuite à y intégrer mon code, mon objectif sera quasiment atteint.

    Y'aura qu'une dernière chose qui me restera à mettre au point. Ce sera de redimensionner les cases (ou agrandir la taille des lignes et des colonnes) au fil des clics pour que les lignes et les colonnes restantes occupent toujours toute la taille du canvas. J'espère poster le résultat final très bientôt.

  8. #8
    Expert confirmé

    Homme Profil pro
    Inscrit en
    Octobre 2008
    Messages
    4 307
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : Belgique

    Informations forums :
    Inscription : Octobre 2008
    Messages : 4 307
    Par défaut
    Citation Envoyé par Arsene12 Voir le message
    Merci de vos réponses.

    En tous cas, si je fais un print(canvas.grid_info()["row"]) dans ma fonction delete(),

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    def delete(event,arg1,arg2):
        #print(canvas.grid_slaves(row, column))
        for canvas in fenetre.grid_slaves():
          print(int(canvas.grid_info()["row"]))
    j'obtiens bien le rang de chaque canvas et non pas le nombre total de rows à chaque fois. Pour le i et j, je suis d'accord, il faut bien partir de 0.
    Heu, j'obtiens toujours le total moi. et tu n'as aucune raison de construire 2500 canvas

  9. #9
    Membre éprouvé
    Profil pro
    Inscrit en
    Février 2003
    Messages
    926
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Février 2003
    Messages : 926
    Par défaut
    Citation Envoyé par VinsS Voir le message
    Heu, j'obtiens toujours le total moi.
    Si je place à cet endroit précis le

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    print(int(canvas.grid_info()["row"]))
    j'obtiens, à chaque appel de la fonction delete(), par simple clic sur le canvas :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    19
    ...
    19
    18
    18
    ...
    18
    17
    17
    ...
    Citation Envoyé par VinsS Voir le message
    et tu n'as aucune raison de construire 2500 canvas
    J'ai abandonné les 2500 canvas. Avec un seul canvas et des rectangles, j'ai plus ce problème de latence. Ce que je cherche à faire maintenant, c'est de redimensionner la largeur des colonnes après qu'il y ait eut suppression d'une colonne. Pour l'instant je n'arrive pas à appliquer la nouvelle largeur que je redéfini pour toutes les colonnes :

    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
    import tkinter as tk
     
    DIM_GRILLE = (10,10)
    #DIM_CASE = 15
    DIM_LIGNE = 1
     
     
    DIM_CASE =[60]
    NBRELignes=[10]
     
     
     
    DIM_CANEVAS = (
        DIM_GRILLE[0]*DIM_CASE[0] + (DIM_GRILLE[0]+1)*DIM_LIGNE,
        DIM_GRILLE[1]*DIM_CASE[0] + (DIM_GRILLE[1]+1)*DIM_LIGNE
    )
     
    def delete(evt) :
     
     
        NBRELignes[0] = NBRELignes[0]-1
        print(DIM_CASE[0])
        DIM_CASE[0]=int(DIM_CANEVAS[0]/NBRELignes[0])    
     
        r = can.find_overlapping(evt.x, evt.y, evt.x, evt.y)
        print(DIM_CASE[0])
        #print(NBRELignes[0])
        if not r :
            return
        ligne, colonne = can.gettags(r[0])[:2]
        iligne, icolonne = int(ligne[1:]), int(colonne[1:])
     
        #print(iligne)
        #print(icolonne)
     
     
        for i in range(iligne+1, DIM_GRILLE[1]+1) :
            can.move('l'+str(i), 0, -(DIM_CASE[0]+DIM_LIGNE))
     
        for i in range(icolonne+1, DIM_GRILLE[0]+1) :
            can.move('c'+str(i), -(DIM_CASE[0]+DIM_LIGNE), 0)
     
        can.delete(ligne)    
        can.delete(colonne)    
        #myGrid()
        can.forget()
     
    fenetre = tk.Tk()
     
    can = tk.Canvas(fenetre, width=DIM_CANEVAS[0], height=DIM_CANEVAS[1], bg='black', highlightthickness=0,
    )
    can.grid()
     
     
    def myGrid():
     
        items = []
        colors = ['red', 'yellow']
        colors2 = 'green'
        y = DIM_LIGNE
        #print(DIM_GRILLE[0])
     
        for ligne in range(DIM_GRILLE[1]) :
            x = DIM_LIGNE
            ids = []
            colors.reverse()
            for col in range(DIM_GRILLE[0]) :
                #print(DIM_CASE[0])    
                i = can.create_rectangle(
                    x, y, x+DIM_CASE[0], y+DIM_CASE[0],
                    #fill=colors[col%2],
                    fill=colors2,
                    width=0,
                    tags='l{} c{}'.format(ligne, col),
                )
                ids.append(i)
                x += DIM_CASE[0] + DIM_LIGNE
            items.append(ids)
            y += DIM_CASE[0] + DIM_LIGNE
     
        can.bind('<Button-1>', delete)
     
    myGrid()
     
    fenetre.mainloop()

  10. #10
    Membre très actif

    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
    Billets dans le blog
    1
    Par défaut
    Salut.

    Citation Envoyé par Arsene12 Voir le message
    Pour l'instant je n'arrive pas à appliquer la nouvelle largeur que je redéfini pour toutes les colonnes
    Sors du contexte de ton application, admettons 12 rangées de case d'une dimension 40, on supprime 1 rangée, comment t'y prendrais-tu pour répartir à peu près équitablement 40 en 11 ?

    Indice, les opérateurs // (reste de la division entière) et % peuvent aider à le faire facilement

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

Discussions similaires

  1. [Interbase 7] Problème temps d'exécution
    Par ch0upette dans le forum InterBase
    Réponses: 9
    Dernier message: 20/02/2007, 23h31
  2. Mesure de temps de latence d'un LCD
    Par Txitxounet dans le forum Bibliothèques
    Réponses: 3
    Dernier message: 08/11/2006, 22h06
  3. Problème de temps de latence avec KeyAdapter
    Par marissa_mean dans le forum AWT/Swing
    Réponses: 16
    Dernier message: 08/10/2006, 20h35
  4. [MySQL] Problème temps d'éxécution trop long
    Par Yo. dans le forum PHP & Base de données
    Réponses: 3
    Dernier message: 13/06/2006, 14h55
  5. [KeyPressed] temps de latence
    Par dieurouille dans le forum AWT/Swing
    Réponses: 1
    Dernier message: 06/06/2006, 21h01

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