DearPyGui
DearPyGui copied to clipboard
Global themes for disabled components not working
Version of Dear PyGui
Version: 1.9.0 Operating System: All
My Issue/Question
Global themes for disabled components not working. Enabled text color takes effect (which is also incorrect).
Expected behavior
Input float text should be red.
Related
https://github.com/hoffstadt/DearPyGui/issues/1401
Standalone, minimal, complete and verifiable example
import dearpygui.dearpygui as dpg
dpg.create_context()
dpg.create_viewport()
dpg.setup_dearpygui()
with dpg.theme() as global_theme:
with dpg.theme_component(dpg.mvInputFloat, enabled_state=True):
dpg.add_theme_color(dpg.mvThemeCol_Text, (255, 0, 0), category=dpg.mvThemeCat_Core)
dpg.bind_theme(global_theme)
with dpg.window(label="tutorial"):
dpg.add_input_float(label="Input float", enabled=False)
dpg.add_input_int(label="Input int", enabled=False)
dpg.show_viewport()
dpg.start_dearpygui()
dpg.destroy_context()
shouldn't the enabled_state
be False
in order to apply the disabled theme?
Anyway, it works for me with enabled_state = False
as I understood from documentation
@marcost83 is right: enabled_state should be False. This makes theme_component(dpg.mvInputFloat)
work as expected; however, theme_component(dpg.mvAll)
doesn't work:
import dearpygui.dearpygui as dpg
dpg.create_context()
dpg.create_viewport(width=600, height=600)
dpg.setup_dearpygui()
with dpg.theme() as global_theme:
with dpg.theme_component(dpg.mvAll, enabled_state=False):
dpg.add_theme_color(dpg.mvThemeCol_Text, (0, 0, 255), category=dpg.mvThemeCat_Core)
dpg.bind_theme(global_theme)
with dpg.window(label="tutorial"):
dpg.add_input_float(label="Input float", enabled=False)
dpg.add_input_int(label="Input int", enabled=False)
dpg.add_button(label="Button", enabled=False)
dpg.show_viewport()
dpg.start_dearpygui()
dpg.destroy_context()
DPG 1.9.1 on Windows.
Another issue is that disabled components do not get grayed out by default. ImGui uses TextDisabled
color for that, but DPG seems to have a different approach with Text
and enabled_state=False
; however, with the current defaults (as of 1.9.1), disabled items retain pure white text color. Neither does dearpygui_ext.themes.create_theme_imgui_yyy
set this up properly.
A workaround for now would be to add something like this to your global theme:
# In 'for', list all the types you need
for comp_type in (dpg.mvMenuItem, dpg.mvButton, dpg.mvText):
with dpg.theme_component(comp_type, enabled_state=False):
dpg.add_theme_color(dpg.mvThemeCol_Text, (0.50 * 255, 0.50 * 255, 0.50 * 255, 1.00 * 255))
If you need to modify a theme created somewhere else (e.g. if you're using themes from DearPyGui_Ext), you can easily wrap it in a context manager like this:
@contextmanager
def dpg_widget(widget: Union[int, str]) -> Generator[Union[int, str], None, None]:
try:
dpg.push_container_stack(widget)
yield widget
finally:
dpg.pop_container_stack()
<...>
my_global_theme = create_theme_imgui_light()
with dpg_widget(my_global_theme):
with dpg.theme_component(...):
# add the stuff you need
Thank you for the workaround. I had a lot of components so I just listed them all from the documentation. Here it is for convenience.
# fix for disabled theme see DearPyGui/issues/2068
comps = [dpg.mvInputText, dpg.mvButton, dpg.mvRadioButton, dpg.mvTabBar, dpg.mvTab, dpg.mvImage, dpg.mvMenuBar, dpg.mvViewportMenuBar, dpg.mvMenu, dpg.mvMenuItem, dpg.mvChildWindow, dpg.mvGroup, dpg.mvDragFloatMulti, dpg.mvSliderFloat, dpg.mvSliderInt, dpg.mvFilterSet, dpg.mvDragFloat, dpg.mvDragInt, dpg.mvInputFloat, dpg.mvInputInt, dpg.mvColorEdit, dpg.mvClipper, dpg.mvColorPicker, dpg.mvTooltip, dpg.mvCollapsingHeader, dpg.mvSeparator, dpg.mvCheckbox, dpg.mvListbox, dpg.mvText, dpg.mvCombo, dpg.mvPlot, dpg.mvSimplePlot, dpg.mvDrawlist, dpg.mvWindowAppItem, dpg.mvSelectable, dpg.mvTreeNode, dpg.mvProgressBar, dpg.mvSpacer, dpg.mvImageButton, dpg.mvTimePicker, dpg.mvDatePicker, dpg.mvColorButton, dpg.mvFileDialog, dpg.mvTabButton, dpg.mvDrawNode, dpg.mvNodeEditor, dpg.mvNode, dpg.mvNodeAttribute, dpg.mvTable, dpg.mvTableColumn, dpg.mvTableRow]
for comp_type in comps:
with dpg.theme_component(comp_type, enabled_state=False):
dpg.add_theme_color(dpg.mvThemeCol_Text, (0.50 * 255, 0.50 * 255, 0.50 * 255, 1.00 * 255))
Disabled components also still appear clickable, such as buttons as mentioned in #1639 . You can use the same theme workaround to get most widgets to appear disabled on hover:
comps = [dpg.mvInputText, dpg.mvButton, dpg.mvRadioButton, dpg.mvTabBar, dpg.mvTab, dpg.mvImage, dpg.mvMenuBar, dpg.mvViewportMenuBar, dpg.mvMenu, dpg.mvMenuItem, dpg.mvChildWindow, dpg.mvGroup, dpg.mvDragFloatMulti, dpg.mvSliderFloat, dpg.mvSliderInt, dpg.mvFilterSet, dpg.mvDragFloat, dpg.mvDragInt, dpg.mvInputFloat, dpg.mvInputInt, dpg.mvColorEdit, dpg.mvClipper, dpg.mvColorPicker, dpg.mvTooltip, dpg.mvCollapsingHeader, dpg.mvSeparator, dpg.mvCheckbox, dpg.mvListbox, dpg.mvText, dpg.mvCombo, dpg.mvPlot, dpg.mvSimplePlot, dpg.mvDrawlist, dpg.mvWindowAppItem, dpg.mvSelectable, dpg.mvTreeNode, dpg.mvProgressBar, dpg.mvSpacer, dpg.mvImageButton, dpg.mvTimePicker, dpg.mvDatePicker, dpg.mvColorButton, dpg.mvFileDialog, dpg.mvTabButton, dpg.mvDrawNode, dpg.mvNodeEditor, dpg.mvNode, dpg.mvNodeAttribute, dpg.mvTable, dpg.mvTableColumn, dpg.mvTableRow]
for comp_type in comps:
with dpg.theme_component(comp_type, enabled_state=False):
dpg.add_theme_color(dpg.mvThemeCol_Text, (0.50 * 255, 0.50 * 255, 0.50 * 255, 1.00 * 255))
dpg.add_theme_color(dpg.mvThemeCol_Button, (45, 45, 48))
dpg.add_theme_color(dpg.mvThemeCol_ButtonHovered, (45, 45, 48))
dpg.add_theme_color(dpg.mvThemeCol_ButtonActive, (45, 45, 48))
Just found this when having the same issue. Fwiw, this is in the documentation: https://dearpygui.readthedocs.io/en/latest/documentation/themes.html?highlight=enabled#theme-for-disabled-items
And modifying their example, this is what worked for me:
def main():
dpg.create_context()
gui = PackageSelectorGUI()
dpg.create_viewport(title='Package Selector', width=600, height=300)
dpg.setup_dearpygui()
if gui.window_id is not None:
dpg.set_primary_window(gui.window_id, True)
disabled_color = (0.50 * 255, 0.50 * 255, 0.50 * 255, 1.00 * 255)
disabled_button_color = (45, 45, 48)
disabled_button_hover_color = (45, 45, 48)
disabled_button_active_color = (45, 45, 48)
with dpg.theme() as disabled_theme:
with dpg.theme_component(dpg.mvButton, enabled_state=False):
dpg.add_theme_color(dpg.mvThemeCol_Text, disabled_color, category=dpg.mvThemeCat_Core)
dpg.add_theme_color(dpg.mvThemeCol_Button, disabled_button_color, category=dpg.mvThemeCat_Core)
dpg.add_theme_color(dpg.mvThemeCol_ButtonHovered, disabled_button_hover_color, category=dpg.mvThemeCat_Core)
dpg.add_theme_color(dpg.mvThemeCol_ButtonActive, disabled_button_active_color, category=dpg.mvThemeCat_Core)
dpg.bind_theme(disabled_theme)
dpg.disable_item("btn")
dpg.show_viewport()
dpg.start_dearpygui()
dpg.destroy_context()
I've done a bit of research on how themes are implemented, and here's what I've got.
There are several distinct issues with the themes:
- On the global theme (the one set with
bind_theme
), theme components that have bothitem_type=dpg.mvAll
andenabled_state=False
are completely ignored. It's the issue described by the OP. - If a theme is bound to an item, and it contains
item_type=dpg.mvAll
components whoseenabled_state
is different from the state of the item itself (e.g.enabled_state=True
on a disabled item), such components are discarded completely and are not inherited by children. Looks somewhat expected at first, but in some cases it leads to really weird results.- In particular, this means you cannot control the appearance of disabled items in a
dpg.group()
by binding a theme to the group with a "disabled"mvAll
component (enabled_state=False
+item_type=dpg.mvAll
). That is, you can't say "in this group, all my disabled widgets should have red text on them" - you'll need to list all the item types one-by-one. Weird? Yes.
- In particular, this means you cannot control the appearance of disabled items in a
- If you specify a particular
item_type
(notmvAll
) on a component, it throws away all other components with the sameitem_type
that were used on parent items. UnlikemvAll
components, styles from different themes are often not merged in this case. The exact behavior depends onitem_type
and the widgets structure, but it's easy to get into situation where some of your styles are completely ignored and you have no idea why.
I might create separate tickets on problems (2) and (3) just to describe them better. However, it won't really help because all three problems can only be solved by completely redesigning the theme hierarchy. It's quite a lot of work, so little chance that it gets implemented any time soon (if it gets implemented at all).
Bottomline: bad news, this issue is rather hard to fix.