Tkinter - ScrolledCanvas - Les objets dépassents du Canevas [Résolu]

Messages postés
2
Date d'inscription
jeudi 4 août 2011
Dernière intervention
12 août 2011
- - Dernière réponse : fireman0865
Messages postés
6
Date d'inscription
jeudi 1 septembre 2011
Dernière intervention
7 octobre 2011
- 7 oct. 2011 à 21:01
Bonjour,

Je suis en train de coder une console qui surveille des abus d'utilisation d'armes sur des jeux en réseau (FPS). A cet effet j'ai codé un ScrolledCanvas qui doit accueillir plusieurs objets (contrôles d'utilisation abusive d'armes). Chacun de ces objets est un objet composite dont les éléments sont réunis par un Frame.

Le problème est que quand je fais un scroll, les objets composites dépassent du canevas (parfois en haut, parfois en bas)

Voici la partie du code qui pose problème :

##############################################################################
# Objets d'interface graphique spécifiques à la gestion des armes

class ScrolledCanvas(Frame):
    def __init__(self, boss, width=100, height=100, bg=None, bd=2, scrollregion=(0, 0, 300, 300), relief=SUNKEN):
        Frame.__init__(self, boss, bd=bd, relief =relief)
        self.can = Canvas(self, width=width-20, height=height-20, bg=bg, scrollregion=scrollregion, bd=1)
        self.can.grid(row=0, column=0)
        scrolv = Scrollbar(self, orient=VERTICAL, command=self.can.yview, bd=1)
        scrolh = Scrollbar(self, orient=HORIZONTAL, command=self.can.xview, bd=1)
        self.can.configure (xscrollcommand=scrolh.set, yscrollcommand=scrolv.set)
        scrolv.grid(row=0, column=1, sticky=NS)
        scrolh.grid(row=1, column=0, sticky=EW)

class ControleArme(Frame):
    """Ligne de contrôle de limitation d'armes"""
    def __init__(self, boss =None, objArme=None, strArme=None):
        Frame.__init__(self, bd =2)
        #Variables de l'objet
        self.objArme = objArme
        self.nomArme = strArme
        self.intSeuil = int(self.objArme.Liste[strArme][0])
        self.CtrleArme = Frame()
        #Instanciation des objets du contrôle
        self.lblClasse = Label(self.CtrleArme, text=self.objArme.Liste[strArme][1], width=7, anchor=W)
        self.lblNature = Label(self.CtrleArme, text=self.objArme.Liste[strArme][2], width=7, anchor=W)
        self.lblArme = Label(self.CtrleArme, text=strArme, width=20, anchor=W)
        self.entSeuil = Entry(self.CtrleArme, width=4)
        self.entSeuil.delete (0, END)
        self.entSeuil.insert(END, self.objArme.Liste[strArme][0])
        self.butAppliquer = Button(self.CtrleArme, text='Appliquer',command=self.ActualiserListeArmes)
        #Mise en place des objets
        self.lblClasse.pack(side=LEFT, anchor=N, padx=1, pady=1)
        self.lblNature.pack(side=LEFT, anchor=N, padx=1, pady=1)
        self.lblArme.pack(side=LEFT, anchor=N, padx=1, pady=1)
        self.entSeuil.pack(side=LEFT, anchor=N, padx=1, pady=1)
        self.butAppliquer.pack(side=LEFT, anchor=N, padx=1, pady=1)
        
    def ActualiserListeArmes(self):
        self.intSeuil = int(self.entSeuil.get())
        self.objArme.ModifierSeuil(self, self.nomArme, self.intSeuil)
        
class ControlesArmes(Frame):
    """Bloc de contrôle des limitations d'armes"""
    def __init__(self, boss=None, objArme=None, width=400, height=300):
        Frame.__init__(self, bd =2, relief =SUNKEN)
        #Reclassement du dictionnaire des armes par numéro d'ordre
        intCompteur = 0
        ListeArmes ={}
        print('Tri de la liste des armes avant mise en place des controles')
        for strArme in objArme.Liste.keys():
            ListeArmes [objArme.Liste[strArme][3]] = (strArme, objArme.Liste[strArme][0], objArme.Liste[strArme][1], objArme.Liste[strArme][2])
            intCompteur += 1
            print (str(objArme.Liste[strArme][3]) + ':' + strArme + ':' + str(objArme.Liste[strArme][0]) + ':' + objArme.Liste[strArme][1] + ':' + objArme.Liste[strArme][2])

        #Instanciation d'un bloc et d'un ascenseur en vue d'y stocker les objets de contrôle d'arme
        ligne = 0
        hauteur = 30
        CadreLC = ScrolledCanvas(self, width=400, height=300, relief=SOLID, scrollregion=(0, 0, 400, (hauteur * intCompteur)))
        CadreLC.pack(expand=NO, fill=BOTH, padx=6, pady=6)
               
        #Instanciation des controles du bloc
        Ctrle = {} #Reset du dictionnaire regroupant les définitions d'objet
        self.CtrleCadre = {}
        for intOrdre in ListeArmes.keys(): #Remplissage du dictionnaire avec les objets + instanciation de ces derniers
            Ctrle [ListeArmes[intOrdre][0]] = ControleArme(CadreLC.can, objArme, ListeArmes[intOrdre][0])
            self.CtrleCadre [ListeArmes[intOrdre][0]] = CadreLC.can.create_window(0, ligne, anchor=NW, window=Ctrle[ListeArmes[intOrdre][0]].CtrleArme)
            ligne += hauteur


Cette section de code est appelée dans une fenêtre principale :
class Application(Frame):
    """Application principale"""
    def __init__(self, boss =None):
        Frame.__init__(self)
        #Chargement des données de limitation d'armes
        self.objArmes = ListeArmes(self)
        self.ChargerArmes()
        print('Verification du chargement des armes')
        for strArme in self.objArmes.Liste.keys():
            print(strArme + ',' + str(self.objArmes.Liste[strArme][0]) + ',' + self.objArmes.Liste[strArme][1]  + ',' + self.objArmes.Liste[strArme][2])
        #Initialisation de la fenêtre de l'application principale
        self.master.title("""Limiteur d'armes - v 1.0""")
        self.mBar = MenuBar(self)
        self.mBar.grid(row=0, column=0, columnspan=2, sticky=W, padx=8, pady=8)
        self.frmArmes = ControlesArmes(self, self.objArmes)
        self.frmArmes.grid (row=1, column=0, sticky=W, padx=8, pady=8)
        #self.frmJoueurs = ControlesJoueurs(self)               #A coder
        #self.frmJoueurs.grid (row=1, column=1, sticky=W)       #A coder
        self.st =ScrolledText(self, baseFont="System 8 normal", width =100, height =5)
        self.st.grid(row=2, column=0, columnspan=2, sticky=W, padx =8, pady =8)


D'avance je remercie quiconque qui aurait une solution à cette question.

Chris
Afficher la suite 

Votre réponse

2 réponses

Meilleure réponse
Messages postés
2
Date d'inscription
jeudi 4 août 2011
Dernière intervention
12 août 2011
3
Merci
J'ai finalement trouvé la réponse à mon problème (un peu par hasard!). Peut-être mon analyse est-elle inexacte, dans ce cas j'espère que les modérateurs voudront bien m'en excuser ; toutefois, si quelqu'un rencontre le même problème, voici ma compréhension de celui-ci :

En fait la frame qui regroupe les objets composites doit être un objet esclave du canvas. Il faut donc rajouter le mot boss lors de son instanciation. En outre, j'ai pu lire qu'il est déconseillé de mélanger des méthodes pack() et grid(), j'ai donc remplacé chaque méthode pack() par une méthode grid(). Avec ces deux opérations, celà fonctionne.


Voici par ailleurs la partie de code modifiée :
[quote=Code Python]
class ControleArme(Frame):
"""Ligne de contrôle de limitation d'armes"""
def __init__(self, boss =None, objArme=None, strArme=None):
Frame.__init__(self, bd =2)
#Variables de l'objet
self.objArme = objArme
self.nomArme = strArme
self.intSeuil = int(self.objArme.Liste[strArme][0])
self.CtrleArme = Frame(boss)
#Instanciation des objets du contrôle
self.lblClasse = Label(self.CtrleArme, text=self.objArme.Liste[strArme][1], width=7, anchor=W)
self.lblNature = Label(self.CtrleArme, text=self.objArme.Liste[strArme][2], width=7, anchor=W)
self.lblArme = Label(self.CtrleArme, text=strArme, width=20, anchor=W)
self.entSeuil = Entry(self.CtrleArme, width=4)
self.entSeuil.delete (0, END)
self.entSeuil.insert(END, self.objArme.Liste[strArme][0])
self.butAppliquer = Button(self.CtrleArme, text='Appliquer',command=self.ActualiserListeArmes)
#Mise en place des objets
self.lblClasse.grid(row=0, column=0, padx=1, pady=1)
self.lblNature.grid(row=0, column=1, padx=1, pady=1)
self.lblArme.grid(row=0, column=2, padx=1, pady=1)
self.entSeuil.grid(row=0, column=3, padx=1, pady=1)
self.butAppliquer.grid(row=0, column=4, padx=1, pady=1)

def ActualiserListeArmes(self):
self.intSeuil = int(self.entSeuil.get())
self.objArme.ModifierSeuil(self, self.nomArme, self.intSeuil)/quote

Dire « Merci » 3

Quelques mots de remerciements seront grandement appréciés. Ajouter un commentaire

Codes Sources 121 internautes nous ont dit merci ce mois-ci

Commenter la réponse de Chris3392
Messages postés
6
Date d'inscription
jeudi 1 septembre 2011
Dernière intervention
7 octobre 2011
0
Merci
salut,surveille bien tes premieres lignes de codes:scrolv.grid(row=0, column=1, sticky=NS)
scrolh.grid(row=1, column=0, sticky=EW)
Commenter la réponse de fireman0865

Vous n'êtes pas encore membre ?

inscrivez-vous, c'est gratuit et ça prend moins d'une minute !

Les membres obtiennent plus de réponses que les utilisateurs anonymes.

Le fait d'être membre vous permet d'avoir un suivi détaillé de vos demandes et codes sources.

Le fait d'être membre vous permet d'avoir des options supplémentaires.