-
Notifications
You must be signed in to change notification settings - Fork 2
Open
Description
An example of a class that implements a toggle button. The structure allows for creating a theme for the button in each state.
Note: requires a local font file. Could not figure out how to re-use the DPG internal ProggyClean.ttf font.
import dearpygui.dearpygui as dpg
dpg.create_context()
dpg.create_viewport()
dpg.setup_dearpygui()
class Fonts(object):
with dpg.font_registry():
default_big = dpg.add_font("FreeMonoOblique.ttf", 30)
default = dpg.add_font("FreeMonoOblique.ttf", 15)
default_small = dpg.add_font("FreeMonoOblique.ttf", 12)
ammeter = dpg.add_font("FreeMonoOblique.ttf", 40)
vout = dpg.add_font("FreeMonoOblique.ttf", 40)
tooltips = default_small
class ThemeToggleMyButton(object):
""" Theme for a Specific Toggle Button
- copy/modify this class for each button theme
"""
name = "mybutton"
with dpg.theme(tag=f"togglebutton_{name}_enabled"): # not active
with dpg.theme_component(dpg.mvButton):
dpg.add_theme_color(dpg.mvThemeCol_Button, (66, 245, 126))
dpg.add_theme_color(dpg.mvThemeCol_ButtonActive, (160, 240, 144))
dpg.add_theme_color(dpg.mvThemeCol_ButtonHovered, (160, 240, 144))
dpg.add_theme_style(dpg.mvStyleVar_FrameRounding, 15)
dpg.add_theme_style(dpg.mvStyleVar_FramePadding, 9, 9)
dpg.add_theme_color(dpg.mvThemeCol_Text, (34, 27, 227))
with dpg.theme(tag=f"togglebutton_{name}_active"): # shows STOP, and red for stop
with dpg.theme_component(dpg.mvButton):
dpg.add_theme_color(dpg.mvThemeCol_Button, (245, 159, 159))
dpg.add_theme_color(dpg.mvThemeCol_ButtonActive, (245, 159, 159))
dpg.add_theme_color(dpg.mvThemeCol_ButtonHovered, (245, 159, 159))
dpg.add_theme_style(dpg.mvStyleVar_FrameRounding, 15)
dpg.add_theme_style(dpg.mvStyleVar_FramePadding, 9, 9)
with dpg.theme(tag=f"togglebutton_{name}_disabled"):
with dpg.theme_component(dpg.mvButton):
dpg.add_theme_color(dpg.mvThemeCol_Button, (161, 168, 160))
dpg.add_theme_color(dpg.mvThemeCol_ButtonActive, (161, 168, 160))
dpg.add_theme_color(dpg.mvThemeCol_ButtonHovered, (161, 168, 160))
dpg.add_theme_style(dpg.mvStyleVar_FrameRounding, 15)
dpg.add_theme_style(dpg.mvStyleVar_FramePadding, 9, 9)
font_enabled = Fonts.default_big
font_disabled = Fonts.default_big
font_active = Fonts.default_big
class ToggleButton(object):
""" ToggleButton Common Code
- dpg.add_button widget should not be accessed directly
"""
STATE_ENABLED = "STATE_ENABLED"
STATE_DISABLED = "STATE_DISABLED"
STATE_ACTIVE = "STATE_ACTIVE"
def __init__(self, name, themeKlass, **kwargs):
""" init
:param name: used to create tag for DPG button, togglebutton_{name}
:param label: list(str, str, str) | str
:param themeKlass: See example
:param kwargs: DPG add_button(args)
"""
kwargs["tag"] = self._tag = f"togglebutton_{name}"
self._state = kwargs.get("state", self.STATE_ENABLED)
self._cb = kwargs.get("callback", None)
self._attrb = {
self.STATE_ENABLED: {
"theme": f"togglebutton_{themeKlass.name}_enabled",
"font": themeKlass.font_enabled
},
self.STATE_DISABLED: {
"theme": f"togglebutton_{themeKlass.name}_disabled",
"font": themeKlass.font_disabled
},
self.STATE_ACTIVE: {
"theme": f"togglebutton_{themeKlass.name}_active",
"font": themeKlass.font_active
},
}
if isinstance(kwargs["label"], str):
self._attrb[self.STATE_ENABLED]["label"] = kwargs["label"]
self._attrb[self.STATE_ACTIVE]["label"] = kwargs["label"]
self._attrb[self.STATE_DISABLED]["label"] = kwargs["label"]
elif isinstance(kwargs["label"], list):
self._attrb[self.STATE_ENABLED]["label"] = kwargs["label"][0]
self._attrb[self.STATE_ACTIVE]["label"] = kwargs["label"][1]
self._attrb[self.STATE_DISABLED]["label"] = kwargs["label"][2]
kwargs["callback"] = self.__cb
kwargs["user_data"] = self
dpg.add_button(**kwargs)
self.set_state()
def __cb(self, sender, app_data, user_data):
""" callback wrapper, sets the button state, then calls user's callback
"""
if self._state == self.STATE_ENABLED:
self.set_state(self.STATE_ACTIVE)
elif self._state == self.STATE_ACTIVE:
self.set_state(self.STATE_ENABLED)
elif self._state == self.STATE_DISABLED:
# could return here and not call the widget's callback, because
# the button is disabled, however, lets do it for most flexibility
pass
if self._cb:
self._cb(sender, app_data, user_data)
def set_state(self, state=STATE_ENABLED):
if state not in [self.STATE_ENABLED, self.STATE_ACTIVE, self.STATE_DISABLED]:
raise ValueError(f"{state} invalid")
self._state = state
dpg.set_item_label(self._tag, self._attrb[self._state]["label"])
dpg.bind_item_theme(self._tag, self._attrb[self._state]["theme"])
dpg.bind_item_font(self._tag, self._attrb[self._state]["font"])
def set_state_label(self, state, label):
if state not in [self.STATE_ENABLED, self.STATE_ACTIVE, self.STATE_DISABLED]:
raise ValueError(f"{state} invalid")
self._attrb[state]["label"] = label
def get_state(self):
return self._state
def get_item_tag(self):
return self._tag
def cb_tb_myTB(sender, app_data, user_data):
"""
:param sender: DPG sender
:param app_data: DPG app_data
:param user_data: Toggle Button Object, use to access class
"""
state = user_data.get_state()
print(f"{sender} {app_data} {state}")
def cb_button_disable(sender, app_data, user_data):
my_toggle_button.set_state(ToggleButton.STATE_DISABLED)
def cb_button_enable(sender, app_data, user_data):
my_toggle_button.set_state(ToggleButton.STATE_ENABLED)
with dpg.window(label="Example Window"):
dpg.add_text("Hello world")
dpg.add_button(tag="disable", label="Disable", callback=cb_button_disable)
dpg.add_button(tag="enable", label="Enable", callback=cb_button_enable)
my_toggle_button = ToggleButton(name="myTB",
themeKlass=ThemeToggleMyButton,
label=["Enabled", "Active", "Disabled"],
width=200,
callback=cb_tb_myTB)
dpg.show_viewport()
dpg.start_dearpygui()
dpg.destroy_context()
Reactions are currently unavailable
Metadata
Metadata
Assignees
Labels
No labels