2

I managed to find in someone who made a class for rounded buttons in tkinter that works great. However the issue I have is there is always a white border. I've tried reading through all of the code and changing all of the colour values but to no avail.

Here is an excerpt of the code working, I've tried to format it as nicely as I could:

from tkinter import Tk, Canvas


class RoundedButton(Canvas):
    def __init__(self, master=None, text: str = "", radius=25, btnforeground="#007CEE", btnbackground="#ffffff",
                 clicked=None, font=("Righteous", 25), *args, **kwargs):
        super(RoundedButton, self).__init__(master, *args, **kwargs)
        self.config(bg=self.master["bg"])
        self.btnbackground = btnbackground
        self.btnforeground = btnforeground
        self.clicked = clicked

        self.radius = radius

        self.rect = self.round_rectangle(0, 0, 0, 0, tags="button", radius=radius, fill=btnbackground)
        self.text = self.create_text(0, 0, text=text, tags="button", fill=btnforeground, font=font,
                                     justify="center")

        self.tag_bind("button", "<ButtonPress>", self.border)
        self.tag_bind("button", "<ButtonRelease>", self.border)
        self.bind("<Configure>", self.resize)

        text_rect = self.bbox(self.text)
        if int(self["width"]) < text_rect[2] - text_rect[0]:
            self["width"] = (text_rect[2] - text_rect[0]) + 10

        if int(self["height"]) < text_rect[3] - text_rect[1]:
            self["height"] = (text_rect[3] - text_rect[1]) + 10

    def round_rectangle(self, x1, y1, x2, y2, radius=25, update=False,
                        **kwargs):  # if update is False a new rounded rectangle's id will be returned else updates existing rounded rect.
        # source: https://stackoverflow.com/a/44100075/15993687
        points = [x1 + radius, y1,
                  x1 + radius, y1,
                  x2 - radius, y1,
                  x2 - radius, y1,
                  x2, y1,
                  x2, y1 + radius,
                  x2, y1 + radius,
                  x2, y2 - radius,
                  x2, y2 - radius,
                  x2, y2,
                  x2 - radius, y2,
                  x2 - radius, y2,
                  x1 + radius, y2,
                  x1 + radius, y2,
                  x1, y2,
                  x1, y2 - radius,
                  x1, y2 - radius,
                  x1, y1 + radius,
                  x1, y1 + radius,
                  x1, y1]

        if not update:
            return self.create_polygon(points, **kwargs, smooth=True)

        else:
            self.coords(self.rect, points)

    def resize(self, event):
        text_bbox = self.bbox(self.text)

        if self.radius > event.width or self.radius > event.height:
            radius = min((event.width, event.height))

        else:
            radius = self.radius

        width, height = event.width, event.height

        if event.width < text_bbox[2] - text_bbox[0]:
            width = text_bbox[2] - text_bbox[0] + 30

        if event.height < text_bbox[3] - text_bbox[1]:
            height = text_bbox[3] - text_bbox[1] + 30

        self.round_rectangle(5, 5, width - 5, height - 5, radius, update=True)

        bbox = self.bbox(self.rect)

        x = ((bbox[2] - bbox[0]) / 2) - ((text_bbox[2] - text_bbox[0]) / 2)
        y = ((bbox[3] - bbox[1]) / 2) - ((text_bbox[3] - text_bbox[1]) / 2)

        self.moveto(self.text, x, y)

    def border(self, event):
        if event.type == "4":
            self.itemconfig(self.rect, fill="#DE8500")
            self.itemconfig(self.text, fill='#ffffff')
            if self.clicked is not None:
                self.clicked()

        else:
            self.itemconfig(self.rect, fill=self.btnbackground)
            self.itemconfig(self.text, fill=self.btnforeground)


window = Tk()
window.geometry("1440x872")
window.configure(bg="#007CEE")

download_button_1 = RoundedButton(
    text="Download",
    font=("Righteous", 30),
    borderwidth=0)
download_button_1.place(
    x=409,
    y=383,
    width=621.0,
    height=105.0
)

window.mainloop()

EDIT: Furas' answer works perfect, for anyone interested in using this rounded button class I would reccommend changing the splinesteps to a higher value at self.create_polygon to help with smoothing

return self.create_polygon(points, **kwargs, smooth=True, splinesteps=10000)
Cai Allin
  • 307
  • 2
  • 11

2 Answers2

3

On Linux works for me

highlightthickness=0

or set color of background

highlightbackground="#007CEE"

eventually

borderwidth=-1

Doc for Canvas (page effbot.org on archive.org) shows all config options.


Before:

enter image description here

After:

enter image description here

furas
  • 134,197
  • 12
  • 106
  • 148
  • Wow, it's always something so simple. Thank you so much man, been racking my head for a good while on this one! – Cai Allin Mar 10 '22 at 22:22
  • 1
    I added link to documentation which shows all config options - because it is hard to remeber all of them. – furas Mar 10 '22 at 22:31
0

2023.01.28: Using: Pop!_OS 22.04 LTS //Python 3.10.6// Tcl/Tk V.8.6

"borderwidth=-1" did not seem to work, but "highlightthickness=0" appeared to do exactly what I expected. Resulting button with rounded corners

And I used an exact copy of the code posted in the original question (by: Cai Allin,Mar 10, 2022 at 21:21) My only changes were in the block for the "Rounded button". First I tested to change the "borderwidth"

download_button_1 = RoundedButton(
    text="Download",
    font=("Righteous", 30),
    borderwidth=-1,
    )    

But this did not result in any visible change.

I then tested to just below the "borderwidth" add:

highlightthickness=0

And this change succeeded in removing the "white border", and it worked regardless whether the settings for the "borderwidth" was "-1" or "0"

  • Where did you put this highlightbackground=0? – toyota Supra Jan 28 '23 at 02:03
  • As it’s currently written, your answer is unclear. Please [edit] to add additional details that will help others understand how this addresses the question asked. You can find more information on how to write good answers [in the help center](/help/how-to-answer). – Community Jan 30 '23 at 06:12