2025, Sep 29 03:31
CustomTkinter में CTkButton पर आइकन क्यों नहीं दिखता और समाधान
CTkImage लेबल में दिखती है पर CTkButton पर नहीं? जानें CustomTkinter में image पैरामीटर को सही तरीके से initialize करने का कारण, न्यूनतम उदाहरण और समाधान।
CustomTkinter UI में बटनों के लिए आइकन जोड़ते समय सब कुछ सीधा लगता है, लेकिन कभी-कभी वही CTkImage लेबल जैसे अन्य विजेट्स में सही दिखता है, पर CTkButton पर चित्र दिखने से इनकार कर देता है। अगर आपके साथ भी ऐसा हुआ है, तो इसकी जड़ अक्सर इस बात में मिलती है कि बटन पर image पैरामीटर कैसे इनिशियलाइज़ किया गया है।
समस्या दोहराने वाला न्यूनतम उदाहरण
import customtkinter as ctk
from PIL import Image
import os
from pathlib import Path
import tkinter
base_dir = Path.home() / "AppData" / "Local" / "TestApp"
icons_dir = os.path.join(base_dir, "Risorse", "icone")
pil_img = Image.open(os.path.join(icons_dir, "icona_cartelle.png"))
ctk_img = ctk.CTkImage(light_image=pil_img, dark_image=pil_img, size=(40, 40))
img_store = {"folder_with_items": ctk_img}
def make_button(container, label_text, row_index, col_index, pad_x):
    global img_store
    btn = ctk.CTkButton(master=container,
                        text=label_text,
                        compound="top",
                        fg_color="white",
                        text_color="black",
                        corner_radius=6,
                        cursor="hand2",
                        hover=True)
    btn._text_label.configure(wraplength=150)
    btn.grid(row=row_index, column=col_index, padx=pad_x, pady=5, sticky="w")
    btn.configure(image=img_store["folder_with_items"])  # विजेट बनने के बाद image असाइन किया गया
    btn.assigned_img = img_store["folder_with_items"]
    print(btn.assigned_img)
    return btn
root = ctk.CTk()
make_button(root, "test", 2, 5, 5)
root.mainloop()यह सेटअप एक बार CTkImage लोड करता है, उसे स्टोर करता है और विजेट बनने के बाद CTkButton को असाइन करता है। पहली नज़र में सब ठीक दिखता है, फिर भी आइकन बटन पर नहीं दिखता, जबकि वही छवि लेबल में काम करती है।
असल में हो क्या रहा है
यह व्यवहार इस बात पर टिका है कि CTkButton का image पैरामीटर कैसे परिभाषित किया गया है। यदि बटन बिना प्रारंभिक image के बनाया गया है और आप बाद में configure(image=...) से जोड़ते हैं, तो आप ऐसी चीज़ बदल रहे होते हैं जो बनाते समय परिभाषित ही नहीं थी। नतीजा: आइकन बटन पर भरोसेमंद तरीके से नहीं दिखता। इसके विपरीत, इसी कोड पथ में लेबल छवि को सही रेंडर करते हैं, जिससे साफ होता है कि समस्या CTkButton के इनिशियलाइज़ेशन में image पैरामीटर को संभालने के तरीके में है।
समाधान: बटन बनाते समय ही image निर्धारित करें
सबसे भरोसेमंद तरीका है कि CTkButton बनाते समय ही image सेट करें। इसके बाद configure(image=...) को कॉल करना पहले से परिभाषित पैरामीटर को अपडेट करने जैसा काम करता है।
import customtkinter as ctk
from PIL import Image
import os
from pathlib import Path
import tkinter
base_dir = Path.home() / "AppData" / "Local" / "TestApp"
icons_dir = os.path.join(base_dir, "Risorse", "icone")
pil_img = Image.open(os.path.join(icons_dir, "icona_cartelle.png"))
ctk_img = ctk.CTkImage(light_image=pil_img, dark_image=pil_img, size=(40, 40))
img_store = {"folder_with_items": ctk_img}
def make_button(container, label_text, row_index, col_index, pad_x):
    global img_store
    btn = ctk.CTkButton(master=container,
                        text=label_text,
                        compound="top",
                        fg_color="white",
                        text_color="black",
                        corner_radius=6,
                        cursor="hand2",
                        hover=True,
                        image=img_store["folder_with_items"])  # बनाते समय image निर्धारित
    btn._text_label.configure(wraplength=150)
    btn.grid(row=row_index, column=col_index, padx=pad_x, pady=5, sticky="w")
    # बाद में, आवश्यकता हो तो आप इसे अपडेट कर सकते हैं
    # btn.configure(image=img_store["folder_with_items"]) 
    btn.assigned_img = img_store["folder_with_items"]
    print(btn.assigned_img)
    return btn
root = ctk.CTk()
make_button(root, "test", 2, 5, 5)
root.mainloop()इस बदलाव के साथ, बटन के पास पहले से image पैरामीटर मौजूद रहता है। बाद की कोई भी configure(image=...) कॉल उसी पर लक्षित होती है, इसलिए आइकन लगातार दिखाई देता है।
यह क्यों महत्वपूर्ण है
UI कोड में, किसी पैरामीटर के साथ विजेट को शुरू से इनिशियलाइज़ करना और उसे बाद में जोड़ने की कोशिश करना, अनुमानित व्यवहार और रुक-रुक कर आने वाली गड़बड़ियों के बीच का फर्क तय कर सकता है। खासकर CustomTkinter में, CTkButton को image के साथ बनाना सुनिश्चित करने से आप बाद में configure() के जरिए उसे बदल सकते हैं, बिना असंगत रेंडरिंग से जूझे। यह तब और काम आता है जब आप आइकन्स का पूल संभालते हैं और उन्हें बटनों व लेबल्स में पुनः उपयोग करते हैं।
मुख्य बातें
यदि CTkButton आइकन नहीं दिखाता जबकि वही CTkImage अन्य विजेट्स में काम कर रही है, तो बटन बनाते समय ही image सेट करें। इसके बाद ज़रूरत अनुसार configure(image=...) से आइकन अपडेट करें। अपनी छवियों को किसी साझा स्टोर में सुलभ रखें ताकि इंटरफेस में बिना दोबारा लोड किए उन्हें पुनः उपयोग किया जा सके।
यह लेख StackOverflow के प्रश्न पर आधारित है, जिसे Andrea Buscetto ने पूछा, और Andrea Buscetto के उत्तर पर।