Python, Tkinter et affichage

Tout ce qui concerne notamment les outils de calcul numérique, de calcul formel ou de géométrie.
[participation réservée aux utilisateurs inscrits]
Règles du forum
Merci de soigner la rédaction de vos messages et de consulter ce sujet avant de poster. Pensez également à utiliser la fonction recherche du forum.
rebouxo
Modérateur honoraire
Modérateur honoraire
Messages : 6962
Inscription : mercredi 15 février 2006, 13:18
Localisation : le havre
Contact :

Python, Tkinter et affichage

Message non lu par rebouxo »

J'ai commis le code suivant (en espérant que les tabulations seront conservées). Ce programme fonctionne fonctionne plutôt bien (C'est la première fois que je fais des fenêtres). Et j'espère ne pas avoir commis trop d'horreur dans les classes et autres bidules de la POO.
But du programme : simuler le lancer d'un grand nombre de fois le jet de deux dès à 6 faces.
Problème : Les effectifs de mes tirages apparaissent après tous les tirages, je voudrais que le tableau se remplisse au fur et à mesure éventuellement en mettant une petite pause entre deux affichages, si c'est vraiment trop rapide. Cela ne me paraît pas d'une grande complexité, mais je ne trouve rien sur internet et je dois dire que je trouve la POO assez lourdingue. Bon de tout façon, avec la POO ou sans, je ne trouve pas comment indiquer ça à Python. Je ne pense pas que cela soit possible en ligne de commande (ou alors j'ai point trouvé) et c'est pour cela que je me suis lancer la dedans. Bon cela doit être possible, puisque j'ai un exemple de code qui le fait, mais impossible d'adapter mon code.

Code : Tout sélectionner

# /usr/bin/python
# -*- coding:latin-1 -*-
def tirages() :
    c = random.randint(1,6)
    d = random.randint(1,6)
    n=c+d
    for j in range(2,13) :
        if n==j : s[j]=s[j]+1
    return s


class Fenetre(object) :
    def __init__(self):
        """Constructeur de la fenêtre principale"""
        self.root=Tk()
        self.root.title("Simulation de lancer de deux dés")
        # Un autre texte
        Label(self.root,text='Entrer un nombre entier').\
                       grid(row = 1,column=1)
        # Un champs de saisie
        self.entre=Entry(self.root)
        self.entre.grid(row=1,column=2)
        # Les résultats
        Label(self.root,text="Nombre : ").grid(row=1,column=3)
        Label(self.root,text="Effectif : ").grid(row=2,column=3)
        for j in range(2,13):
            Label(self.root,text=j).grid(row=1,column=j+3)
            Label(self.root,text='0').grid(row=2,column=j+3)

        # Bouton lancer
        self.lancer=Button(self.root,text='Lancer',command=self.lanceTirage).\
                     grid(row=3,column=1)
        # Bouton quitter
        self.bouton=Button(self.root,text='Quitter',command=self.root.quit).\
                     grid(row=3,column=2)
        self.root.mainloop()
    # Fin de la construction de l'objet fenêtre

    def lanceTirage(self) :
            "Récupère le nombre rentre et lance le tirage"
            self.valeur=self.entre.get() # on récupère la chaine de caractère
            N=int(self.valeur)               # on la transforme en entier
            for i in range(1,N+1):
                tirages()
            for i in range(2,13):
                Label(self.root,text=s[i]).grid(row=2,column=i+3)
    
        # Fin du tirage

####### MAIN #####

if __name__ == '__main__' :
    import random
    from Tkinter import *
    s=[0]*13
    f=Fenetre()
Merci pour tout début de commencement d'idée.
Olivier
A line is a point that went for a walk. Paul Klee.
Par solidarité, pas de MP.
Arnaud
Modérateur honoraire
Modérateur honoraire
Messages : 7097
Inscription : lundi 28 août 2006, 13:18
Localisation : Allemagne
Contact :

Re: Python, Tkinter et affichage

Message non lu par Arnaud »

rebouxo a écrit : Problème : Les effectifs de mes tirages apparaissent après tous les tirages, je voudrais que le tableau se remplisse au fur et à mesure éventuellement en mettant une petite pause entre deux affichages, si c'est vraiment trop rapide.
J'ai du mal à cerner ce que tu veux.

Un truc genre :
"Tirages précédents : ...."
"Tirage : ...."
"Effectifs de tous les tirages : ...."

?
Arnaud
Un peu d'info - Pyromaths - Pas d'aide en MP (non plus)
projetmbc
Utilisateur chevronné
Utilisateur chevronné
Messages : 2238
Inscription : samedi 29 décembre 2007, 00:58

Re: Python, Tkinter et affichage

Message non lu par projetmbc »

Bonsoir,
il est tard et je ne connais pas trop Tkinter. Une réponse arrivera sûrement plus rapidement sur ce forum, j'y traîne.

Ceci étant, on ne voit pas trop ce que tu veux faire. Peux-tu préciser ta question ?
rebouxo
Modérateur honoraire
Modérateur honoraire
Messages : 6962
Inscription : mercredi 15 février 2006, 13:18
Localisation : le havre
Contact :

Re: Python, Tkinter et affichage

Message non lu par rebouxo »

projetmbc a écrit :Bonsoir,
il est tard et je ne connais pas trop Tkinter. Une réponse arrivera sûrement plus rapidement sur ce forum, j'y traîne.

Ceci étant, on ne voit pas trop ce que tu veux faire. Peux-tu préciser ta question ?
Zut et damned, moi qui croyait avoir été clair :D .
Je veux juste que les effectifs soient actualisés au fur et à mesure. Actuellement n'apparaissent que les effectifs finaux (au bout de N lancers). Je voudrais qu'à chaque lancer qui donne la somme i le compteur s soit incrémenté (ça c'est fait) mais surtout que l'affichage soit modifié.

Au départ on a :
2 3 4 5 6 ....
0 0 0 0 0 ...
Après un lancer je voudrais avoir
2 3 4 5 6...
0 0 1 0 0 ...
Après deux lancers
2 3 4 5 6...
0 0 1 0 1...

Bref je voudrais réécrire par dessus ma ligne effectif et que ces modifications soient visibles.

En espérant être plus clair.

Olivier
A line is a point that went for a walk. Paul Klee.
Par solidarité, pas de MP.
projetmbc
Utilisateur chevronné
Utilisateur chevronné
Messages : 2238
Inscription : samedi 29 décembre 2007, 00:58

Re: Python, Tkinter et affichage

Message non lu par projetmbc »

Bpnjour.

Maintenant que la question est clarifiée, voici une proposition avec une pause pour éviter des "scintillements" lors des changements.

Code : Tout sélectionner

# /usr/bin/python
# -*- coding:latin-1 -*-

# SOURCE : http://forum.mathematex.net/logiciels-mathematiques-f7/python-tkinter-et-affichage-t12314.html

import random
import time
from Tkinter import *

def tirages(s) :
    c = random.randint(1,6)
    d = random.randint(1,6)    
    n = c+d 
    
    for j in range(2,13) :
        if n == j :
            s[j] = s[j]+1
    return s


class Fenetre(object) :
    def __init__(self):
        """Constructeur de la fenêtre principale"""
        self.root=Tk()
        self.root.title(u"Simulation de lancer de deux dés")
        
        # Un autre texte
        Label(self.root,
              text='Entrer un nombre entier').grid(row = 1, column = 1)

        # Un champs de saisie
        self.entre=Entry(self.root)
        self.entre.grid(row = 1, column = 2)

        # Les résultats
        Label(self.root,
              text="Nombre : ").grid(row = 1, column = 3)
        Label(self.root,
              text="Effectif : ").grid(row = 2, column = 3)
        
        for j in range(2,13):
            Label(self.root,
                  text=j).grid(row = 1, column = j+3)
            Label(self.root,
                  text='0').grid(row = 2, column = j+3)

        # Bouton lancer
        self.lancer=Button(self.root,
                           text='Lancer',
                           command=self.lanceTirage).grid(row = 3, column = 1)
        # Bouton quitter
        self.bouton=Button(self.root,
                           text='Quitter',
                           command=self.root.quit).grid(row = 3, column = 2)
        
        self.root.mainloop()

    def lanceTirage(self) :
        "Récupère le nombre rentre et lance le tirage"
        self.valeur=self.entre.get() # on récupère la chaine de caractère
       
        N = int(self.valeur)               # on la transforme en entier

        s = [0]*13
        for i in range(1, N+1):
            if i != 1:
                time.sleep(0.1)

            tirages(s)
            
            for i in range(2, 13):
                Label(self.root,
                      text = s[i]).grid(row = 2, column = i+3)
            
            self.root.update() # On force la mise à jour sinon elle se fera tout à la fin

####### MAIN #####

if __name__ == '__main__' :   
    f = Fenetre()
La difficulté technique est de penser que la mise à jour est automatique. Ce n'est pas le cas, il faut la forcer via self.root.update(). Ceci doit sûrement provenir du fait que Tkinter attend que tous les traitements soient faits pour faire une mise à jour visuelle.

Si je trouve la motivation j'essaierais de comparer cela avec le comportement de pyqt.
Arnaud
Modérateur honoraire
Modérateur honoraire
Messages : 7097
Inscription : lundi 28 août 2006, 13:18
Localisation : Allemagne
Contact :

Re: Python, Tkinter et affichage

Message non lu par Arnaud »

Presque la même solution, car l'import de time n'est pas nécessaire :

Code : Tout sélectionner

# -*- coding: utf-8 -*-
# /usr/bin/python
# -*- coding:utf-8 -*-

def tirages() :
    global t
    c = random.randint(1,6)
    d = random.randint(1,6)
    n=c+d
    for j in range(2,13) :
        if n==j : t[j]=t[j]+1
    return t


class Fenetre(object) :
    def __init__(self):
        """Constructeur de la fenêtre principale"""
        self.root=Tk()
        self.root.title("Simulation de lancer de deux dés")
        # Un autre texte
        Label(self.root,text='Entrer un nombre entier').\
                       grid(row = 1,column=1)
        # Un champs de saisie
        self.entre=Entry(self.root)
        self.entre.grid(row=1,column=2)
        # Les résultats
        Label(self.root,text="Nombre : ").grid(row=1,column=3)
        Label(self.root,text="Effectif : ").grid(row=2,column=3)
        for j in range(2,13):
            Label(self.root,text=j).grid(row=1,column=j+3)
            Label(self.root,text='0').grid(row=2,column=j+3)

        # Bouton lancer
        self.lancer=Button(self.root,text='Lancer',command=self.lanceTirage).\
                     grid(row=3,column=1)
        # Bouton quitter
        self.bouton=Button(self.root,text='Quitter',command=self.root.quit).\
                     grid(row=3,column=2)
        self.root.mainloop()
    # Fin de la construction de l'objet fenêtre

    def lanceTirage(self) :
            "Récupère le nombre rentre et lance le tirage"
            global t
            self.valeur=self.entre.get() # on récupère la chaine de caractère
            N=int(self.valeur)               # on la transforme en entier    
            t=[0]*13
            for i in range(1,N+1):
                tirages()
            print s, t
            for i in range(2,13):
                while s[i] < t[i]:
                    s[i] += 1
                    self.root.after(500, Label(self.root,text=s[i]).grid(row=2,column=i+3))
                    self.root.update()
   
        # Fin du tirage

####### MAIN #####

if __name__ == '__main__' :
    import random
    from Tkinter import *
    s=[0]*13
    f=Fenetre()
Màj toutes les demi-secondes, si tu veux autre chose, il suffit de modifier le 500.
Arnaud
Un peu d'info - Pyromaths - Pas d'aide en MP (non plus)
rebouxo
Modérateur honoraire
Modérateur honoraire
Messages : 6962
Inscription : mercredi 15 février 2006, 13:18
Localisation : le havre
Contact :

Re: Python, Tkinter et affichage

Message non lu par rebouxo »

Bon ben pour quelques choses d'aussi simples, pourquoi qu'on trouve rien chez google.

Merci à tous les deux.
A line is a point that went for a walk. Paul Klee.
Par solidarité, pas de MP.
projetmbc
Utilisateur chevronné
Utilisateur chevronné
Messages : 2238
Inscription : samedi 29 décembre 2007, 00:58

Re: Python, Tkinter et affichage

Message non lu par projetmbc »

J'ai utilisé Google car je ne connais pas Tkinter (je vais utiliser PyQt pour mon projet).
Répondre
  • Sujets similaires
    Réponses
    Vues
    Dernier message