Étendre les canvas dans la fenêtre principale

L’auteur de ce sujet a trouvé une solution à son problème.
Auteur du sujet

Bonjour à tous, Je suis en train de construire un interface graphique avec Tkinter.

Je dispose d’une fenêtre avec deux canvas, mon objectif est que ces canvas s’étendent sur l’axe Y pour le canvas de gauche et sur les deux axes pour le canvas de droite le problême est que même s’il me semble avoir passé les bons paramètres au gestionnaire de positionnement (en l’occurrence fill et expand) ces deux Widgets gardent désespérément la même taille lorsque l’on redimensionne la fenêtre. Je suppose que cela est due au frames dont hérite les canvas mais voici le code:

 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
import tkinter as tk
from tkinter import BOTH, BOTTOM, TOP, LEFT, RIGHT, HORIZONTAL, VERTICAL, X, Y, NW, YES

class DoubleCanvas(tk.Frame):
    def __init__(self, master=None):
        tk.Frame.__init__(self, master)
        self.pack()
        # Left Canvas
        self.left_frame = tk.Frame(self)
        self.left_canvas = tk.Canvas(self.left_frame, bg='#FFFFFF', width=300, height=300, scrollregion=(0, 0, 500, 500))
        hbar = tk.Scrollbar(self.left_frame, orient=HORIZONTAL)
        hbar.pack(side=BOTTOM, fill=X)
        hbar.config(command=self.left_canvas.xview)
        vbar = tk.Scrollbar(self.left_frame, orient=VERTICAL)
        vbar.pack(side=RIGHT, fill=Y)
        vbar.config(command=self.left_canvas.yview)
        self.left_canvas.config(xscrollcommand=hbar.set, yscrollcommand=vbar.set)
        self.left_canvas.pack(side=RIGHT, expand=True, fill=Y)
        self.left_frame.pack(side=RIGHT, expand=True, fill=Y)
        # Right Canvas
        self.right_frame = tk.Frame(self)
        self.right_canvas = tk.Canvas(self.right_frame, bg='#FFFFFF', width=300, height=300, scrollregion=(0, 0, 500, 500))
        hbar = tk.Scrollbar(self.right_frame, orient=HORIZONTAL)
        hbar.pack(side=BOTTOM, fill=X)
        hbar.config(command=self.right_canvas.xview)
        vbar = tk.Scrollbar(self.right_frame, orient=VERTICAL)
        vbar.pack(side=RIGHT, fill=Y)
        vbar.config(command=self.right_canvas.yview)
        self.right_canvas.config(xscrollcommand=hbar.set, yscrollcommand=vbar.set)
        self.right_canvas.pack(side=LEFT, expand=True, fill=BOTH)
        self.right_frame.pack(side=LEFT, expand=True)

if __name__ == '__main__':
    root = tk.Tk()
    root.title("Double Canvas")
    app = DoubleCanvas(master=root)
    app.mainloop()

Toute aide sera la bienvenue.

Édité par Nogs

+0 -0
Auteur du sujet

Cette réponse a aidé l’auteur du sujet

Et la réponse est… triviale.

Je commettais une erreur en passant à l’initialisation de la Frame scrollable l’instance de la classe DoubleCanvas, il fallait en fait lui passer l’instance racine soit l’instance de classe de Tk.

 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
class DoubleCanvas(tk.Frame):
    def __init__(self, master=None):
        tk.Frame.__init__(self, master)
        self.pack()
        self.left_frame = tk.Frame(master)
        vscrollbar = tk.Scrollbar(self.left_frame, orient=VERTICAL)
        vscrollbar.pack(fill=Y, side=RIGHT, expand=FALSE)
        hscrollbar = tk.Scrollbar(self.left_frame, orient=HORIZONTAL)
        hscrollbar.pack(fill=X, side=BOTTOM, expand=FALSE)
        self.left_canvas = tk.Canvas(self.left_frame, bd=0, highlightthickness=0, yscrollcommand=vscrollbar.set,
                                xscrollcommand=hscrollbar.set, bg='#FFFFFF')
        self.left_canvas.pack(side=LEFT, fill=Y)
        vscrollbar.config(command=self.left_canvas)
        hscrollbar.config(command=self.left_canvas)
        self.left_frame.pack(side=LEFT, fill=Y)

        self.right_frame = tk.Frame(master)
        vscrollbar2 = tk.Scrollbar(self.right_frame, orient=VERTICAL)
        vscrollbar2.pack(fill=Y, side=RIGHT, expand=FALSE)
        hscrollbar2 = tk.Scrollbar(self.right_frame, orient=HORIZONTAL)
        hscrollbar2.pack(fill=X, side=BOTTOM, expand=FALSE)
        self.right_canvas = tk.Canvas(self.right_frame, bd=0, highlightthickness=0, yscrollcommand=vscrollbar2.set,
                                xscrollcommand=hscrollbar2.set, bg='#FFFFFF')
        self.right_canvas.pack(side=LEFT, fill=BOTH, expand=True)
        vscrollbar2.config(command=self.right_canvas)
        hscrollbar2.config(command=self.right_canvas)
        self.right_frame.pack(side=RIGHT, fill=BOTH, expand=YES)

if __name__ == '__main__':
    root = tk.Tk()
    root.title("Double Canvas")
    app = DoubleCanvas(master=root)
    app.mainloop()

De manière plus propre et aussi pour éviter ce genre de boulettes, on peut imaginer utiliser plusieurs classes contentant des Widgets spécifiques et une classe principale pour faire tourner l’application:

 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
import tkinter as tk
from tkinter import BOTH, BOTTOM, TOP, LEFT, RIGHT, HORIZONTAL, VERTICAL, X, Y, NW, YES, TRUE, FALSE


class ScrollableCanvas(tk.Frame):
    def __init__(self, master, canvas_fill=None, canvas_expand=False, *args, **kwargs ):
        tk.Frame.__init__(self, master, *args, **kwargs )
        vscrollbar = tk.Scrollbar(self, orient=VERTICAL)
        vscrollbar.pack(fill=Y, side=RIGHT, expand=FALSE)
        hscrollbar = tk.Scrollbar(self, orient=HORIZONTAL)
        hscrollbar.pack(fill=X, side=BOTTOM, expand=FALSE)
        self.canvas = tk.Canvas(self, bd=0, highlightthickness=0, yscrollcommand=vscrollbar.set,
                                xscrollcommand=hscrollbar.set, bg='#FFFFFF')
        self.canvas.pack(side=LEFT, fill=canvas_fill, expand=canvas_expand)
        vscrollbar.config(command=self.canvas)
        hscrollbar.config(command=self.canvas)

class DoubleCanvasApp(tk.Frame):
    def __init__(self, master=None):
        tk.Frame.__init__(self, master)
        self.left_frame = ScrollableCanvas(master, canvas_fill=Y)
        self.left_frame.pack(side=LEFT, fill=Y)
        self.right_frame = ScrollableCanvas(master, canvas_fill=BOTH, canvas_expand=True)
        self.right_frame.pack(side=RIGHT, fill=BOTH, expand=YES)
        self.pack()

if __name__ == '__main__':
    root = tk.Tk()
    root.title("Double Canvas")
    app = DoubleCanvasApp(master=root)
    app.mainloop()

Voila, au cas où cela pourrait aider quelqu’un.

Édité par Nogs

+0 -0
Vous devez être connecté pour pouvoir poster un message.
Connexion

Pas encore inscrit ?

Créez un compte en une minute pour profiter pleinement de toutes les fonctionnalités de Zeste de Savoir. Ici, tout est gratuit et sans publicité.
Créer un compte