-
-
Notifications
You must be signed in to change notification settings - Fork 688
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Tree View with Table in DearPyGui #2379
Comments
Hello @Umbrella167 - have you tried to create such a layout using existing DPG widgets? If it doesn't work for you, could you please describe what goes wrong? |
@v-ein These two images illustrate the functionality I am trying to achieve. Specifically, it can be found in: dpg.show_imgui_demo() --> Tables & Columns --> Tree view I attempted to nest a tree node within a table; however, I was unable to achieve the desired effect. Could you please advise on how to accomplish this using the existing DPG widgets, or if there's another approach I should consider? Thank you for your assistance. |
Well, I must admit that it's not trivial but here is a workaround. The problem with existing widgets is that DPG implements table rows as containers, whereas in ImGui it all works a bit differently... In DPG, you can't put a tree structure in different table rows because that would mean overlapping containers in the code (a tree node is a container, and a table row is a container too). So the workaround simulates the tree by explicitly showing and hiding the rows whenever a node is expanded or collapsed. One more problem is that in the current version, the #!/usr/local/bin/python3
from contextlib import contextmanager
from typing import Generator, Union
import dearpygui.dearpygui as dpg
dpg.create_context()
dpg.setup_dearpygui()
dpg.create_viewport(title="Test", width=500, height=300)
INDENT_STEP = 14 # actually depends on font size
def on_row_clicked(sender, value, user_data):
# Make sure it happens quickly and without flickering
with dpg.mutex():
# We don't want to highlight the selectable as "selected"
dpg.set_value(sender, False)
table, row = user_data
root_level, node = dpg.get_item_user_data(row)
# First of all let's toggle the node's "expanded" status
is_expanded = not dpg.get_value(node)
dpg.set_value(node, is_expanded)
# All children *beyond* this level (but not on this level) will be hidden
hide_level = 10000 if is_expanded else root_level
# Now manage the visibility of all the children as necessary
rows = dpg.get_item_children(table, slot=1)
root_idx = rows.index(row)
# We don't want to look at rows preceding our current "root" node
rows = rows[root_idx + 1:]
for child_row in rows:
child_level, child_node = dpg.get_item_user_data(child_row)
if child_level <= root_level:
break
if child_level > hide_level:
dpg.hide_item(child_row)
else:
dpg.show_item(child_row)
hide_level = 10000 if dpg.get_value(child_node) else child_level
@contextmanager
def table_tree_node(*cells: str, leaf: bool = False) -> Generator[Union[int, str] , None, None]:
table = dpg.top_container_stack()
cur_level = dpg.get_item_user_data(table) or 0
node = dpg.generate_uuid()
with dpg.table_row(user_data=(cur_level, node)) as row:
with dpg.group(horizontal=True, horizontal_spacing=0):
dpg.add_selectable(span_columns=True, callback=on_row_clicked, user_data=(table, row))
dpg.add_tree_node(
tag=node,
label=cells[0],
indent=cur_level*INDENT_STEP,
leaf=leaf,
bullet=leaf,
default_open=True)
for label in cells[1:]:
dpg.add_text(label)
try:
dpg.set_item_user_data(table, cur_level + 1)
yield node
finally:
dpg.set_item_user_data(table, cur_level)
def add_table_tree_leaf(*cells: str) -> Union[int, str]:
with table_tree_node(*cells, leaf=True) as node:
pass
return node
with dpg.window():
dpg.set_primary_window(dpg.last_item(), True)
# We need to adjust padding so that widgets of different types are positioned properly
with dpg.theme() as table_theme:
with dpg.theme_component(dpg.mvAll):
# Frame padding affects vertical positioning of add_text items within the table
dpg.add_theme_style(dpg.mvStyleVar_FramePadding, 4, 0)
with dpg.table(
borders_outerV=True,
borders_outerH=True,
row_background=True,
policy=dpg.mvTable_SizingFixedFit):
dpg.bind_item_theme(dpg.last_item(), table_theme)
dpg.add_table_column(label="Name", width_stretch=True)
dpg.add_table_column(label="Size")
dpg.add_table_column(label="Type")
with table_tree_node("Root", "--", "Folder"):
with table_tree_node("Music", "--", "Folder"):
add_table_tree_leaf("File1_a.wav", "123000", "Audio file")
add_table_tree_leaf("File1_b.wav", "456000", "Audio file")
with table_tree_node("My favourite", "--", "Folder"):
add_table_tree_leaf("Some pop.wav", "456000", "Audio file")
with table_tree_node("Textures", "--", "Folder"):
add_table_tree_leaf("Image001.png", "203128", "Image file")
add_table_tree_leaf("Copy of Image001.png", "203256", "Image file")
add_table_tree_leaf("Copy of Image001 (Final2).png", "203512", "Image file")
add_table_tree_leaf("desktop.ini", "1024", "System file")
dpg.show_viewport()
dpg.start_dearpygui()
dpg.destroy_context() |
@v-ein Thank you so much for your detailed explanation and the workaround you provided! Your method is ingenious and exactly what I needed. This was a huge help to me. Thanks again for your patience and assistance! |
I would like to request the addition of a feature in DearPyGui that allows the creation of a tree view inside a table. This feature is inspired by ImGui's capability to create such a layout. Below is a reference implementation using ImGui:
cpp
复制
if (ImGui::TreeNode("Tree view"))
{
static ImGuiTableFlags flags = ImGuiTableFlags_BordersV | ImGuiTableFlags_BordersOuterH | ImGuiTableFlags_Resizable | ImGuiTableFlags_RowBg | ImGuiTableFlags_NoBordersInBody;
}
Benefits
Enhanced UI Capability: This feature would allow users to create more complex and organized interfaces, especially useful for applications dealing with hierarchical data.
Consistency with ImGui: Users familiar with ImGui's functionality would have an easier transition and more powerful tools at their disposal.
Implementation Notes
The feature should support various table flags such as resizable columns, row backgrounds, and customizable column widths.
It should allow the nesting of tree nodes within table cells, maintaining the hierarchical structure.
Thank you for considering this feature request. Implementing this would greatly enhance the versatility and usability of DearPyGui for many developers.
The text was updated successfully, but these errors were encountered: