python-3.xclasstkintertkinter-canvas

tkinter General canvas creating using class


I know I can do this...

import tkinter as tk

root=tk.Tk()
root.geometry("800x600")
#Note if '=' is used, i.e. root.geometry=("800x600")
# then tkinter root(window) does NOT display full area

canv1=tk.Canvas(bg="green", height=150, width=200)
canv1.place(x=20,y=10)

root.mainloop()

Ideally I'd like to make many canvasses, and as I'm learning about classes, it occurred to me that this could be done employing classes, so I could more easily and more rapidly instantiate a user defined canvas like so... canv2 = InstantCanvas(orange, 100, 250)

I thought this seemed reasonable:

import tkinter as tk

root=tk.Tk()
root.geometry("400x300")

class InstantCanvas():
    def __init__(self, background, height, width):
        self = self.tk.Canvas(background, height, width)
        # trying to achieve "my_user_canvas.

#Note if '=' is used, i.e. root.geometry=("800x600")
# then tkinter root(window) does NOT display full area

# Reference canvas, manually made
canv1=tk.Canvas(bg="green", height=150, width=200)
canv1.place(x=20,y=10)

canv2 = InstantCanvas("orange", 100, 250)
canv2.place(x=40,y=50)

root.mainloop()

but I get an error... AttributeError: 'InstantCanvas' object has no attribute 'tk'

So I have to put import tkinter as tk inside the class init function? Seems odd and redundant, but I tried anyway...

import tkinter as tk

root=tk.Tk()
root.geometry("400x300")

class InstantCanvas():
    import tkinter as tk
    def __init__(self, background, height, width):
        self = self.tk.Canvas(background, height, width)
        # trying to achieve "my_user_canvas.

#Note if '=' is used, i.e. root.geometry=("800x600")
# then tkinter root(window) does NOT display full area

# Reference canvas, manually made
canv1=tk.Canvas(bg="green", height=150, width=200)
canv1.place(x=20,y=10)

canv2 = InstantCanvas("orange", 100, 250)
canv2.place(x=40,y=50)

root.mainloop()

Now I get too many argument errors, specifically, Canvas.init() takes from 1 to 3 positional arguments but 4 were given, but I thought init kinda overlooked self as a 'hard' argument, but if I leave self out, then my init function will fail to 'connect' to the instantiated object. So how?

Feedback on why it's not working and how to make it work would be gratefully appreciated. Tq.


Solution

  • For your purpose, it seems that it'd be better to just subclass tk.Canvas, then call super() to initialize the canvas.

    import tkinter as tk
    
    
    class InstantCanvas(tk.Canvas):
        def __init__(self, background, height, width):
            super().__init__(bg=background, height=height, width=width)
            # trying to achieve "my_user_canvas.
    
    
    root = tk.Tk()
    root.geometry("400x300")
    
    # Reference canvas, manually made
    canv1 = tk.Canvas(bg="green", height=150, width=200)
    canv1.place(x=20, y=10)
    
    canv2 = InstantCanvas("orange", 100, 250)
    canv2.place(x=40, y=50)
    
    root.mainloop()