TomSchimansky/CustomTkinter

CTkToplevel overrides any changes to the titlebar icon.

63OR63 opened this issue · 4 comments

Issue: CTkToplevel overrides any custom changes to the titlebar icon.

The problem lies in the following code within the __init__ method of ctk_toplevel.py (lines 41-47):

        try:
            # Set Windows titlebar icon
            if sys.platform.startswith("win"):
                customtkinter_directory = os.path.dirname(os.path.dirname(os.path.abspath(__file__)))
                self.after(200, lambda: self.iconbitmap(os.path.join(customtkinter_directory, "assets", "icons", "CustomTkinter_icon_Windows.ico")))
        except Exception:
            pass

Context: In CustomTkinter, iconphoto is not implemented and calling it doesn't set _iconbitmap_method_called to True. As a result, CTk doesn't recognize it was called and overrides the icon settings with a default one. To work around this, I'm wrapping the CTk._windows_set_titlebar_icon method to ensure iconphoto can be used without interference.

While there’s no check for _iconbitmap_method_called or similar in the __init__ method of ctk_toplevel.py, I'll mention it here for completeness, even though it may not be directly relevant.

def custom_set_titlebar_icon(self):
    try:
        base_path = Path(sys._MEIPASS)
    except Exception:
        base_path = Path(".")
    try:
        resource_path = base_path / APP_ICONS["png"]
        self.iconphoto(True, tk.PhotoImage(file=resource_path))
    except Exception:
        pass

_CTk = ctk.CTk
if hasattr(_CTk, "_windows_set_titlebar_icon"):
    _CTk._windows_set_titlebar_icon = custom_set_titlebar_icon

@63OR63 Try to update it after its check (i.e., after 200 ms). Try the following updated code:

try:
        resource_path = base_path / APP_ICONS["png"]
        sefl._tkimg = tk.PhotoImage(file=resource_path)
        self.after(250, lambda: self.iconphoto(True, sefl._tkimg))
        
except Exception:
        pass

It will certainly work, but the question is: should it be so? It's a flawed approach. I don’t want the titlebar icon to flicker in my app 250 ms after the window opens. Hardcoding icon in __init__ is certainly an oversight, and this behavior is a bug. At the very least, it should check for _iconbitmap_method_called, if that's the approach chosen to be used in every other relevant part of the CustomTkinter codebase.

@63OR63 Yes, it's a known bug. But @TomSchimansky is currently not accepting any fixing PR #2162, so this version of this repository is being continued. To know more, read #2343 .

It's appreciable you pointed it out.
Regards.

@dipeshSam
I didn’t come across that PR, so it seems my issue is a duplicate. Oops.
Also, thanks for the information about current project status. I hope the author will find motivation to continue it.