CustomTkinter icon indicating copy to clipboard operation
CustomTkinter copied to clipboard

CTKComboBox arrow graphic issue

Open Guilherme-Mello opened this issue 1 year ago • 12 comments

So, i've been playing arround a bit with customtkinter.

While using the comboBox, o noticed an issue with the graphics as shown below:

image image image

As you can see, there is 3 white dots on the arrow. i have no idea about why this happens.

Please, can anybody help me?

Guilherme-Mello avatar Jun 24 '24 00:06 Guilherme-Mello

I think its supposed to be part of the theme that u have applied.

v-pun215 avatar Jun 24 '24 03:06 v-pun215

It's not an error or bug. It's part of design.

Regards.

dipeshSam avatar Jun 24 '24 03:06 dipeshSam

I think its supposed to be part of the theme that u have applied.

So, i did not applied any theme, i just set the colors manually. Even if i use all colors default but keeping the sizings, i encounter these dots.

It's not an error or bug. It's part of design.

Regards.

is there any way to exchange this arrow dropdown icon for something custom?

Guilherme-Mello avatar Jun 24 '24 11:06 Guilherme-Mello

@Guilherme-Mello Can you have sample reproducible code? It might be helpful to clarify it.

dipeshSam avatar Jun 24 '24 11:06 dipeshSam

@Guilherme-Mello Can you have sample reproducible code? It might be helpful to clarify it.

Sure!

import customtkinter as ctk
from PIL import Image as Img
from UI_Tools import *


class App(ctk.CTk):
    def __init__(self, title, size):

        # Main setup
        super().__init__()
        #ctk.set_appearance_mode("system")
        self.title(title)

        self.geometry(f'{size[0]}x{size[1]}+{int(abs((self.winfo_screenwidth()/2)-(size[0]/2)))}+{int(abs((self.winfo_screenheight()/2)-(size[1]/2)))}')
        self.minsize(size[0],size[1])
        self.maxsize(size[0],size[1])
        #Define Images:
        image_bg = Img.open("assets/frame0/AppOne.png")
        background = ctk.CTkImage(light_image=image_bg, dark_image=image_bg, size=(size))
        bg_lbl = ctk.CTkLabel(self, text="", image=background, width=size[0],height=size[1])
        bg_lbl.place(x=0, y=0)

        AppMenu(self)
        # Run
        self.mainloop()

def AppMenu(self):
    #self._fg_color = "#797979"
    Font_Audiowide15 = ctk.CTkFont(family="Audiowide", size = 15)
    Font_Audiowide10 = ctk.CTkFont(family="Audiowide", size = 10)
    DynamicButton(self, x=19,y=140,H=35,W=154, 
                  text= "Connect", 
                  font=Font_Audiowide15,
                  Tcolor="#4B00EA",
                  TcolorClick = "#0B0022",
                  TcolorHover = "#7653BF",
                  Bcolor = "#D9D9D9",
                  BcolorHover = "#D9D9D9",
                  radius = 6,
                  cmd = None,
                  bgColor= "#797979",
                )
    

    DynamicButton(self, x=188,y=99,H=35,W=241, 
                  text= "Send data", 
                  font=Font_Audiowide15,
                  Tcolor="#4B00EA",
                  TcolorClick = "#0B0022",
                  TcolorHover = "#7653BF",
                  Bcolor = "#D9D9D9",
                  BcolorHover = "#D9D9D9",
                  radius = 6,
                  cmd = None,
                  bgColor= "#797979",
                )
    

    comboboxCOM = ctk.CTkComboBox(self, 
                               values=["COM1", "COM2"],
                               command=None, 
                               variable=None,
                               width=102,
                               height=33,
                               corner_radius=5,
                               border_width=1,
                               border_color = "#FFFFFF",
                               text_color = "#000000",
                               button_color = "#D9D9D9",
                               button_hover_color = "#FFFFFF",
                               fg_color = "#D9D9D9",
                               bg_color = "#959595",
                               font= Font_Audiowide10,
                               justify=CENTER,
                               state = "readonly"
                               )
    comboboxCOM.place(x=71,y=59)


    # comboboxBAUD = ctk.CTkComboBox(self, 
    #                            values=["9600", "4800"],
    #                            command=None, 
    #                            variable=None,
    #                            width=102,
    #                            height=33,
    #                            corner_radius=5,
    #                            border_width=1,
    #                            border_color="#FFFFFF",
    #                            text_color="#000000",
    #                            button_color="#D9D9D9",
    #                            button_hover_color="#FFFFFF",
    #                            fg_color="#D9D9D9",
    #                            bg_color= "#959595",
    #                            font= Font_Audiowide10,
    #                            justify=CENTER,
    #                            state = "readonly"
    #                            )
    # comboboxBAUD.place(x=71,y=100)


    comboboxBAUD = ctk.CTkComboBox(self, 
                               values=["9600", "4800"],
                               command=None, 
                               variable=None,
                               width=102,
                               height=33,
                               corner_radius=5,
                               border_width=1,
                              #  border_color="#FFFFFF",
                              #  text_color="#000000",
                              #  button_color="#D9D9D9",
                              #  button_hover_color="#FFFFFF",
                              #  fg_color="#D9D9D9",
                              #  bg_color= "#959595",
                               font= Font_Audiowide10,
                               justify=CENTER,
                               #state = "readonly"
                               )
    comboboxBAUD.place(x=71,y=100)



    entryData = ctk.CTkEntry(self,
                             placeholder_text="Data to send",
                             width=241,
                             height=33,
                             corner_radius=5,
                             border_width=1,
                             border_color="#FFFFFF",
                             text_color="#000000",
                             fg_color="#D9D9D9",
                             bg_color= "#959595",
                             font= Font_Audiowide10
                             )
    entryData.place(x=188,y=60)


    textboxHistory = ctk.CTkTextbox(self,
                             width=410,
                             height=105,
                             corner_radius=5,
                             border_spacing=4,
                             border_width=1,
                             border_color="#FFFFFF",
                             text_color="#000000",
                             fg_color="#D9D9D9",
                             bg_color= "#959595",
                             font= Font_Audiowide10,
                             state="disable"
                             )
    textboxHistory.place(x=20,y=185)


    labelStatus = ctk.CTkLabel(self,
                               text = "Status",
                               width = 50,
                               height = 17,
                               text_color = "#000000",
                               bg_color= "#797979",
                               font = Font_Audiowide15,
                               compound = CENTER,
                               justify = CENTER
                               )
    labelStatus.place(x=284,y=149)
    

App('Luna Serial Terminal', (450,300))

The expected window for the code above is this:

image

Guilherme-Mello avatar Jun 24 '24 12:06 Guilherme-Mello

@Guilherme-Mello Can you have sample reproducible code? It might be helpful to clarify it.

Sure!

import customtkinter as ctk
from PIL import Image as Img
from UI_Tools import *


class App(ctk.CTk):
    def __init__(self, title, size):

        # Main setup
        super().__init__()
        #ctk.set_appearance_mode("system")
        self.title(title)

        self.geometry(f'{size[0]}x{size[1]}+{int(abs((self.winfo_screenwidth()/2)-(size[0]/2)))}+{int(abs((self.winfo_screenheight()/2)-(size[1]/2)))}')
        self.minsize(size[0],size[1])
        self.maxsize(size[0],size[1])
        #Define Images:
        image_bg = Img.open("assets/frame0/AppOne.png")
        background = ctk.CTkImage(light_image=image_bg, dark_image=image_bg, size=(size))
        bg_lbl = ctk.CTkLabel(self, text="", image=background, width=size[0],height=size[1])
        bg_lbl.place(x=0, y=0)

        AppMenu(self)
        # Run
        self.mainloop()

def AppMenu(self):
    #self._fg_color = "#797979"
    Font_Audiowide15 = ctk.CTkFont(family="Audiowide", size = 15)
    Font_Audiowide10 = ctk.CTkFont(family="Audiowide", size = 10)
    DynamicButton(self, x=19,y=140,H=35,W=154, 
                  text= "Connect", 
                  font=Font_Audiowide15,
                  Tcolor="#4B00EA",
                  TcolorClick = "#0B0022",
                  TcolorHover = "#7653BF",
                  Bcolor = "#D9D9D9",
                  BcolorHover = "#D9D9D9",
                  radius = 6,
                  cmd = None,
                  bgColor= "#797979",
                )
    

    DynamicButton(self, x=188,y=99,H=35,W=241, 
                  text= "Send data", 
                  font=Font_Audiowide15,
                  Tcolor="#4B00EA",
                  TcolorClick = "#0B0022",
                  TcolorHover = "#7653BF",
                  Bcolor = "#D9D9D9",
                  BcolorHover = "#D9D9D9",
                  radius = 6,
                  cmd = None,
                  bgColor= "#797979",
                )
    

    comboboxCOM = ctk.CTkComboBox(self, 
                               values=["COM1", "COM2"],
                               command=None, 
                               variable=None,
                               width=102,
                               height=33,
                               corner_radius=5,
                               border_width=1,
                               border_color = "#FFFFFF",
                               text_color = "#000000",
                               button_color = "#D9D9D9",
                               button_hover_color = "#FFFFFF",
                               fg_color = "#D9D9D9",
                               bg_color = "#959595",
                               font= Font_Audiowide10,
                               justify=CENTER,
                               state = "readonly"
                               )
    comboboxCOM.place(x=71,y=59)


    # comboboxBAUD = ctk.CTkComboBox(self, 
    #                            values=["9600", "4800"],
    #                            command=None, 
    #                            variable=None,
    #                            width=102,
    #                            height=33,
    #                            corner_radius=5,
    #                            border_width=1,
    #                            border_color="#FFFFFF",
    #                            text_color="#000000",
    #                            button_color="#D9D9D9",
    #                            button_hover_color="#FFFFFF",
    #                            fg_color="#D9D9D9",
    #                            bg_color= "#959595",
    #                            font= Font_Audiowide10,
    #                            justify=CENTER,
    #                            state = "readonly"
    #                            )
    # comboboxBAUD.place(x=71,y=100)


    comboboxBAUD = ctk.CTkComboBox(self, 
                               values=["9600", "4800"],
                               command=None, 
                               variable=None,
                               width=102,
                               height=33,
                               corner_radius=5,
                               border_width=1,
                              #  border_color="#FFFFFF",
                              #  text_color="#000000",
                              #  button_color="#D9D9D9",
                              #  button_hover_color="#FFFFFF",
                              #  fg_color="#D9D9D9",
                              #  bg_color= "#959595",
                               font= Font_Audiowide10,
                               justify=CENTER,
                               #state = "readonly"
                               )
    comboboxBAUD.place(x=71,y=100)



    entryData = ctk.CTkEntry(self,
                             placeholder_text="Data to send",
                             width=241,
                             height=33,
                             corner_radius=5,
                             border_width=1,
                             border_color="#FFFFFF",
                             text_color="#000000",
                             fg_color="#D9D9D9",
                             bg_color= "#959595",
                             font= Font_Audiowide10
                             )
    entryData.place(x=188,y=60)


    textboxHistory = ctk.CTkTextbox(self,
                             width=410,
                             height=105,
                             corner_radius=5,
                             border_spacing=4,
                             border_width=1,
                             border_color="#FFFFFF",
                             text_color="#000000",
                             fg_color="#D9D9D9",
                             bg_color= "#959595",
                             font= Font_Audiowide10,
                             state="disable"
                             )
    textboxHistory.place(x=20,y=185)


    labelStatus = ctk.CTkLabel(self,
                               text = "Status",
                               width = 50,
                               height = 17,
                               text_color = "#000000",
                               bg_color= "#797979",
                               font = Font_Audiowide15,
                               compound = CENTER,
                               justify = CENTER
                               )
    labelStatus.place(x=284,y=149)
    

App('Luna Serial Terminal', (450,300))

The expected window for the code above is this:

image

The design i'm planning to implement is this:

image

Above is a printscreen from my figma project, of course, the comboBoxes has its own design, no problem, but the white dots on the arrows is really annoying. Hope somebody can help me.

Guilherme-Mello avatar Jun 24 '24 12:06 Guilherme-Mello

Currently there is no built in handle available to customize this problem in CustomTkinter. @TomSchimansky should take a look into this matter.

Regards.

dipeshSam avatar Jun 24 '24 13:06 dipeshSam

@Guilherme-Mello This is another scaling issue with customtkinter. The arrows will only look good if Windows screen scaling is set to 100%. I guess yours is higher.

MuzzyGH avatar Sep 04 '24 07:09 MuzzyGH

@Guilherme-Mello This is another scaling issue with customtkinter. The arrows will only look good if Windows screen scaling is set to 100%. I guess yours is higher.

I don't think this is an issue with scaling. My OS scaling is set to 100% and I still see these dots.

vojtechportes avatar Sep 17 '24 13:09 vojtechportes

Well, in this case this might be caused by increasing the size of the widget (or its components). By default these artefacts appear with higher scaling.

By the way, unless all these simple issues are fixed I consider customtkinter unusable (after all its main function is supposed to be improving tkinter's aesthetics).

MuzzyGH avatar Sep 17 '24 13:09 MuzzyGH

It looks like the arrow is drawing in draw_engine.py


def draw_dropdown_arrow(self, x_position: Union[int, float], y_position: Union[int, float], size: Union[int, float]) :
     
        x_position, y_position, size = round(x_position), round(y_position), round(size)
        requires_recoloring = False
       
        if self.preferred_drawing_method == "polygon_shapes" or self.preferred_drawing_method == "circle_shapes":
            if not self._canvas.find_withtag("dropdown_arrow"):
                self._canvas.create_line(0, 0, 0, 0, tags="dropdown_arrow", width=round(size / 3), joinstyle=tkinter.ROUND, capstyle=tkinter.ROUND)
                self._canvas.tag_raise("dropdown_arrow")
                requires_recoloring = True

            self._canvas.coords("dropdown_arrow",
                                x_position - (size / 2),
                                y_position - (size / 5),
                                x_position,
                                y_position + (size / 5),
                                x_position + (size / 2),
                                y_position - (size / 5))

        elif self.preferred_drawing_method == "font_shapes":
            if not self._canvas.find_withtag("dropdown_arrow"):
                self._canvas.create_text(0, 0, text="Y", font=("CustomTkinter_shapes_font", -size), tags="dropdown_arrow", anchor=tkinter.CENTER)
                self._canvas.tag_raise("dropdown_arrow")
                requires_recoloring = True

            self._canvas.itemconfigure("dropdown_arrow", font=("CustomTkinter_shapes_font", -size))
            self._canvas.coords("dropdown_arrow", x_position, y_position)

        return requires_recoloring

In windows system, It goes here: self._canvas.create_text(0, 0, text="Y", font=("CustomTkinter_shapes_font", -size), tags="dropdown_arrow", anchor=tkinter.CENTER) replace with self._canvas.create_text(0, 0, text="😊", font=("CustomTkinter_shapes_font", -size), tags="dropdown_arrow", anchor=tkinter.CENTER)

Image

self._canvas.create_text(0, 0, text="🔽", font=("CustomTkinter_shapes_font", -size), tags="dropdown_arrow", anchor=tkinter.CENTER)

Image

self._canvas.create_text(0, 0, text="👇", font=("CustomTkinter_shapes_font", -size), tags="dropdown_arrow", anchor=tkinter.CENTER)

Image

Maybe the font of Y has something wrong, now we can use other char to fix this problem.

RonTang avatar May 01 '25 10:05 RonTang

@RonTang That's great!

dipeshSam avatar May 02 '25 02:05 dipeshSam