TomSchimansky / CustomTkinter

A modern and customizable python UI-library based on Tkinter
MIT License
10.84k stars 1.02k forks source link

Custom Scaling error: ''AttributeError: 'CTkButton' object has no attribute '_desired_width''' #2282

Open dracid opened 4 months ago

dracid commented 4 months ago

When I follow official custom scaling guide, and apply that to a gui with a button, I get the following error:

customtkinter version: 5.2.2
Traceback (most recent call last):

  File ~\anaconda3\Lib\site-packages\spyder_kernels\py3compat.py:356 in compat_exec
    exec(code, globals, locals)

  File d:\gdrive\projects\python scripts\modern_python_gui_customtkinter\embedding_in_tk_sgskip_customtk.py:21
    ctk.set_widget_scaling(dpi_scale)  # widget dimensions and text size

  File ~\anaconda3\Lib\site-packages\customtkinter\__init__.py:74 in set_widget_scaling
    ScalingTracker.set_widget_scaling(scaling_value)

  File ~\anaconda3\Lib\site-packages\customtkinter\windows\widgets\scaling\scaling_tracker.py:32 in set_widget_scaling
    cls.update_scaling_callbacks_all()

  File ~\anaconda3\Lib\site-packages\customtkinter\windows\widgets\scaling\scaling_tracker.py:54 in update_scaling_callbacks_all
    set_scaling_callback(cls.window_dpi_scaling_dict[window] * cls.widget_scaling,

  File ~\anaconda3\Lib\site-packages\customtkinter\windows\widgets\ctk_button.py:136 in _set_scaling
    super()._set_scaling(*args, **kwargs)

  File ~\anaconda3\Lib\site-packages\customtkinter\windows\widgets\core_widget_classes\ctk_base_class.py:228 in _set_scaling
    super().configure(width=self._apply_widget_scaling(self._desired_width),

AttributeError: 'CTkButton' object has no attribute '_desired_width'

I use latest, customtkinter 5.2.2, platform Windows 11. Btw, it would be helpful to include that float_value is supposed to be like '1.5' instead of '150%'. The example code that produces the error is here (modified from matplotlib tk example:

"""
===============
Embedding in customtkinter
===============

"""

import customtkinter as ctk
import numpy as np

from importlib.metadata import version
print('customtkinter version: ' + version('customtkinter'))

# Implement the default Matplotlib key bindings.
from matplotlib.backend_bases import key_press_handler
from matplotlib.backends.backend_tkagg import (FigureCanvasTkAgg,
                                               NavigationToolbar2Tk)
from matplotlib.figure import Figure

dpi_scale = 1.5
ctk.set_widget_scaling(dpi_scale)  # widget dimensions and text size
ctk.set_window_scaling(dpi_scale)  # window geometry dimensions

ctk.set_appearance_mode('dark')
ctk.set_default_color_theme('blue')

root = ctk.CTk()
root.wm_title("Embedding in Tk")

fig = Figure(figsize=(5, 4), dpi=100)
t = np.arange(0, 3, .01)
ax = fig.add_subplot()
line, = ax.plot(t, 2 * np.sin(2 * np.pi * t))
ax.set_xlabel("time [s]")
ax.set_ylabel("f(t)")

canvas = FigureCanvasTkAgg(fig, master=root)  # A tk.DrawingArea.
canvas.draw()

# pack_toolbar=False will make it easier to use a layout manager later on.
toolbar = NavigationToolbar2Tk(canvas, root, pack_toolbar=False)
toolbar.update()

canvas.mpl_connect(
    "key_press_event", lambda event: print(f"you pressed {event.key}"))
canvas.mpl_connect("key_press_event", key_press_handler)

button_quit = ctk.CTkButton(master=root, text="Quit", command=root.destroy)

def update_frequency(new_val):
    # retrieve frequency
    f = float(new_val)

    # update data
    y = 2 * np.sin(2 * np.pi * f * t)
    line.set_data(t, y)

    # required to update canvas and attached toolbar!
    canvas.draw()

slider_update = ctk.CTkSlider(root, from_=1, to=5, orientation=ctk.HORIZONTAL,
                              command=update_frequency)

# Packing order is important. Widgets are processed sequentially and if there
# is no space left, because the window is too small, they are not displayed.
# The canvas is rather flexible in its size, so we pack it last which makes
# sure the UI controls are displayed as long as possible.
button_quit.pack(side=ctk.BOTTOM)
slider_update.pack(side=ctk.BOTTOM)
toolbar.pack(side=ctk.BOTTOM, fill=ctk.X)
canvas.get_tk_widget().pack(side=ctk.TOP, fill=ctk.BOTH, expand=True)

root.mainloop()