Home > Software engineering >  Is there a way to reduce the amount of times the canvas.create_rectangle method appears in my code?
Is there a way to reduce the amount of times the canvas.create_rectangle method appears in my code?

Time:09-27

So I created a Tkinter app, with 3 frames. The user interface is designed with Figma, so the objects are explicitly called.

I managed to reduce the canvas object being explicitly called by creating a top-level class that inherits from Canvas.

class MyCanvas (Canvas):
    def __init__(self, *args, **kwargs):
        Canvas.__init__(self, *args, **kwargs)
        self['bg'] = "#FFFFFF",
        self['height'] = 519,
        self['width'] = 862,
        self['bd'] = 0,
        self['highlightthickness'] = 0,
        self['relief'] = "ridge"
        self.place(x=0,y=0)

This is one of the frames:

class HomePage (tk.Frame):
    def __init__(self, parent, controller):
        tk.Frame.__init__(self, parent)
        self.controller = controller
        canvas = MyCanvas(self)

Now, the code after this is:

canvas.create_rectangle(
            0.0,
            0.0,
            587.0,
            519.0,
            fill="#00A4D2",
            outline="")

This block of code appears three times (I have 3 frames). Is there a way to reduce the repetition of this?

Different methods I tried:

  1. @classmethod
@classmethod
        def Createrect(cls):
            self.create_rectangle(0.0,
            0.0,
            587.0,
            519.0,
            fill="#00A4D2",
            outline="")

Then calling that method after the

canvas = MyCanvas(self)

Didn't work.

  1. Creating another top level class
class createrect(MyCanvas)
def createrect1():
MyCanvas.create_rectangle(.0,
            0.0,
            587.0,
            519.0,
            fill="#00A4D2",
            outline="")

Another trial and error, that obviously didn't hit.

Thanks for your future help!

Right now the app is working, but it is 600 lines. Initially it was 900 (lol) but due to me discovering the Inheritance concept, it was reduced to 600 . Still I believe it can be reduced further. And, my apologies if the code is not robust, this is my first Python app.

I hope I gave all the necessary details. Feel free to comment if additional details are needed.

CodePudding user response:

I am not sure if you are overthinking or I am underthinking :)

Option 1: Just create a regular method in MyCanvas to call it multiple times. Only works for the current canvas.

class MyCanvas(Canvas):
    def __init__(self, *args, **kwargs):
        super().__init__(self, *args, **kwargs)
        self['bg'] = "#FFFFFF",
        self['height'] = 519,
        self['width'] = 862,
        self['bd'] = 0,
        self['highlightthickness'] = 0,
        self['relief'] = "ridge"
        self.place(x=0, y=0)
        
        self.create_rect()
        self.create_rect()
        self.create_rect()

    def create_rect(self):
        self.create_rectangle(0.0, 0.0, 587.0, 519.0, fill="#00A4D2", outline="")

Option 2: Have a MainCanvas that holds the reusable methods

class MainCanvas(Canvas):
    def __init__(self, *args, **kwargs):
        super().__init__(*args, **kwargs)

    def create_rect(self):
        self.create_rectangle(0.0, 0.0, 587.0, 519.0, fill="#00A4D2", outline="")


class MyCanvas(MainCanvas):
    def __init__(self, *args, **kwargs):
        super().__init__(self, *args, **kwargs)
        self['bg'] = "#FFFFFF",
        self['height'] = 519,
        self['width'] = 862,
        self['bd'] = 0,
        self['highlightthickness'] = 0,
        self['relief'] = "ridge"
        self.place(x=0, y=0)

        self.create_rect()
        self.create_rect()
        self.create_rect()

CodePudding user response:

rectangle items are expected as one of the form:

pathName create rectangle x1 y1 x2 y2 ?option value ...?
pathName create rectangle coordList ?option value ...?

So all is needed to create an rectangle are a list of coordinates or as written out positional arguments. After those coordinates you have a variety of optional keyword arguments. With this in mind you can easily do something like:

coords = [x1,y1,x2,y2]
options= {
    'fill':"#00A4D2", 
    'outline':""}
[self.create_rectangle(*coords,**options) for i in range(4)]

This code uses the python feature unpacking and a list comprehension. Also note that I did not use self. as those variables seems pointless to keep in my opinion and get garbage collected.

Short enough ?

  • Related