israel-dryer / ttkbootstrap

A supercharged theme extension for tkinter that enables on-demand modern flat style themes inspired by Bootstrap.
MIT License
1.98k stars 393 forks source link

Support for custom widget classes? #592

Open DevilXD opened 4 months ago

DevilXD commented 4 months ago

Desktop (please complete the following information):

ttkbootstrap: 1.10.1 OS: Windows

Describe the bug

I've got this error:

Traceback (most recent call last):
  (...)
  File "gui.py", line 1903, in __init__
    LinkLabel(
  File "gui.py", line 348, in __init__
    super().__init__(*args, **kwargs)
  File "d:\(...)\lib\site-packages\ttkbootstrap\style.py", line 4950, in __init__
    ttkstyle = Bootstyle.update_ttk_widget_style(
  File "d:\(...)\lib\site-packages\ttkbootstrap\style.py", line 5049, in update_ttk_widget_style
    builder_method = builder.name_to_method(method_name)
  File "d:\(...)\lib\site-packages\ttkbootstrap\style.py", line 1086, in name_to_method
    func = getattr(StyleBuilderTTK, method_name)
AttributeError: type object 'StyleBuilderTTK' has no attribute 'create_link_label_style'

The code from gui.py:

class LinkLabel(ttk.Label):
    def __init__(self, *args, link: str, **kwargs) -> None:
        self._link: str = link
        # style provides font and foreground color
        if "style" not in kwargs:
            kwargs["style"] = "Link.TLabel"
        elif not kwargs["style"]:
            super().__init__(*args, **kwargs)
            return
        if "cursor" not in kwargs:
            kwargs["cursor"] = "hand2"
        if "padding" not in kwargs:
            # W, N, E, S
            kwargs["padding"] = (0, 2, 0, 2)
        super().__init__(*args, **kwargs)
        self.bind("<ButtonRelease-1>", lambda e: webopen(self._link))

Is this not supported? Am I doing something wrong? I've just installed the package to try it out on my project.

To Reproduce

Unfortunately, I'm unable to reproduce this issue "in lab environment", at least in a way that gives me the exact same exception. I have this:

from tkinter import Tk
from tkinter.font import nametofont

from ttkbootstrap import ttk

root = Tk()
style = ttk.Style()
default_font = nametofont("TkDefaultFont")
link_font = default_font.copy()
link_font.config(underline=True)
style.configure("Link.TLabel", font=link_font, foreground="blue")

class CustomLabel(ttk.Label):
    def __init__(self, *args, link: str, **kwargs):
        self._link: str = link
        if "style" not in kwargs:
            kwargs["style"] = "Link.TLabel"
        super().__init__(*args, **kwargs)

CustomLabel(root, link="...")

..., but it gives me a different exception:

Traceback (most recent call last):
  (...)
  File "d:\(...)\test.py", line 24, in <module>
    CustomLabel(link="...")
  File "d:\(...)\test.py", line 21, in __init__
    super().__init__(*args, **kwargs)
  File "d:\(...)\lib\site-packages\ttkbootstrap\style.py", line 4947, in __init__
    if Style.get_instance().style_exists_in_theme(style):
AttributeError: 'NoneType' object has no attribute 'style_exists_in_theme'

Expected behavior

Well... No error, at the very least?

Screenshots

No response

Additional context

No response