docs/source/documentation/tables.rst
The table API is a low level API that can be used to create tables.
It can also be used as a layout mechanism. Tables are composed of multiple components which include columns, rows, cells, and the actual items to be displayed. The best place to learn about the various configuration options for the table is by running the demo!
Below is the minimum example for creating a table
Code
.. code-block:: python
import dearpygui.dearpygui as dpg
dpg.create_context()
with dpg.window(label="Tutorial"):
with dpg.table(header_row=False):
# use add_table_column to add columns to the table,
# table columns use child slot 0
dpg.add_table_column()
dpg.add_table_column()
dpg.add_table_column()
# add_table_next_column will jump to the next row
# once it reaches the end of the columns
# table next column use slot 1
for i in range(0, 4):
with dpg.table_row():
for j in range(0, 3):
dpg.add_text(f"Row{i} Column{j}")
dpg.create_viewport(title='Custom Title', width=800, height=600)
dpg.setup_dearpygui()
dpg.show_viewport()
dpg.start_dearpygui()
dpg.destroy_context()
.. note:: The maximum number of columns is 64.
multiple items can go into a single cell by creating a cell as shown
Code
.. code-block:: python
import dearpygui.dearpygui as dpg
dpg.create_context()
with dpg.window(label="Tutorial"):
with dpg.table(header_row=False, resizable=True, policy=dpg.mvTable_SizingStretchProp,
borders_outerH=True, borders_innerV=True, borders_innerH=True, borders_outerV=True):
dpg.add_table_column(label="Header 1")
dpg.add_table_column(label="Header 2")
dpg.add_table_column(label="Header 3")
# once it reaches the end of the columns
for i in range(0, 4):
with dpg.table_row():
for j in range(0, 3):
with dpg.table_cell():
dpg.add_button(label=f"Row{i} Column{j} a")
dpg.add_button(label=f"Row{i} Column{j} b")
dpg.create_viewport(title='Custom Title', width=800, height=600)
dpg.setup_dearpygui()
dpg.show_viewport()
dpg.start_dearpygui()
dpg.destroy_context()
You can control the borders of the table using the
borders_innerH, borders_innerV, borders_outerH,
and borders_outerV keywords. You can also turn on alternate
row coloring using the row_background keyword.
Code
.. code-block:: python
import dearpygui.dearpygui as dpg
dpg.create_context()
with dpg.window(label="Tutorial"):
with dpg.table(header_row=False, row_background=True,
borders_innerH=True, borders_outerH=True, borders_innerV=True,
borders_outerV=True):
# use add_table_column to add columns to the table,
# table columns use child slot 0
dpg.add_table_column()
dpg.add_table_column()
dpg.add_table_column()
# add_table_next_column will jump to the next row
# once it reaches the end of the columns
# table next column use slot 1
for i in range(0, 4):
with dpg.table_row():
for j in range(0, 3):
dpg.add_text(f"Row{i} Column{j}")
dpg.create_viewport(title='Custom Title', width=800, height=600)
dpg.setup_dearpygui()
dpg.show_viewport()
dpg.start_dearpygui()
dpg.destroy_context()
Column headers are simply shown by setting header_row to True
and setting the label of the columns.
Code
.. code-block:: python
import dearpygui.dearpygui as dpg
dpg.create_context()
with dpg.window(label="Tutorial"):
with dpg.table(header_row=True):
# use add_table_column to add columns to the table,
# table columns use slot 0
dpg.add_table_column(label="Header 1")
dpg.add_table_column(label="Header 2")
dpg.add_table_column(label="Header 3")
# add_table_next_column will jump to the next row
# once it reaches the end of the columns
# table next column use slot 1
for i in range(0, 4):
with dpg.table_row():
for j in range(0, 3):
dpg.add_text(f"Row{i} Column{j}")
dpg.create_viewport(title='Custom Title', width=800, height=600)
dpg.setup_dearpygui()
dpg.show_viewport()
dpg.start_dearpygui()
dpg.destroy_context()
In order for a table to have resizable columns,
the resizable and borders_innerV keywords must be set to True.
You can also set the sizing policy
keyword, policy, using the following options
Policy: | mvTable_SizingFixedFit | mvTable_SizingFixedSame | mvTable_SizingStretchProp | mvTable_SizingStretchSame
Below is an example of setting the stretch policy for the entire table
.. code-block:: python
import dearpygui.dearpygui as dpg
dpg.create_context()
with dpg.window(label="Tutorial"):
with dpg.table(header_row=False, resizable=True, policy=dpg.mvTable_SizingStretchProp,
borders_outerH=True, borders_innerV=True, borders_outerV=True):
dpg.add_table_column(label="Header 1")
dpg.add_table_column(label="Header 2")
dpg.add_table_column(label="Header 3")
# add_table_next_column will jump to the next row
# once it reaches the end of the columns
# table next column use slot 1
for i in range(0, 4):
with dpg.table_row():
for j in range(0, 3):
dpg.add_text(f"Row{i} Column{j}")
dpg.create_viewport(title='Custom Title', width=800, height=600)
dpg.setup_dearpygui()
dpg.show_viewport()
dpg.start_dearpygui()
dpg.destroy_context()
Fixed
Below is an example of setting the fixed fit policy for the entire table
.. code-block:: python
import dearpygui.dearpygui as dpg
dpg.create_context()
with dpg.window(label="Tutorial"):
# Only available if scrollX/scrollY are disabled and stretch columns are not used
with dpg.table(header_row=False, policy=dpg.mvTable_SizingFixedFit, resizable=True, no_host_extendX=True,
borders_innerV=True, borders_outerV=True, borders_outerH=True):
dpg.add_table_column(label="Header 1")
dpg.add_table_column(label="Header 2")
dpg.add_table_column(label="Header 3")
for i in range(0, 4):
with dpg.table_row():
for j in range(0, 3):
dpg.add_button(label=f"Row{i} Column{j} a")
dpg.create_viewport(title='Custom Title', width=800, height=600)
dpg.setup_dearpygui()
dpg.show_viewport()
dpg.start_dearpygui()
dpg.destroy_context()
Mixed
You can also set columns individually by using the
width_fixed or width_stretch keyword along with the
init_width_or_weight keyword.
.. code-block:: python
import dearpygui.dearpygui as dpg
dpg.create_context()
with dpg.window(label="Tutorial"):
with dpg.table(header_row=True, policy=dpg.mvTable_SizingFixedFit, row_background=True, reorderable=True,
resizable=True, no_host_extendX=False, hideable=True,
borders_innerV=True, borders_outerV=True, borders_innerH=True,
borders_outerH=True):
dpg.add_table_column(label="AAA", width_fixed=True)
dpg.add_table_column(label="BBB", width_fixed=True)
dpg.add_table_column(label="CCC", width_stretch=True, init_width_or_weight=0.0)
dpg.add_table_column(label="DDD", width_stretch=True, init_width_or_weight=0.0)
for i in range(0, 5):
with dpg.table_row():
for j in range(0, 4):
if j == 2 or j == 3:
dpg.add_text(f"Stretch {i},{j}")
else:
dpg.add_text(f"Fixed {i}, {j}")
dpg.create_viewport(title='Custom Title', width=800, height=600)
dpg.setup_dearpygui()
dpg.show_viewport()
dpg.start_dearpygui()
dpg.destroy_context()
There are a large number of options available for table columns which are best learned through running the demo, these include
====================== ============= =========== keyword default value description ====================== ============= =========== init_width_or_weight 0.0 sets the starting width (fixed policy) or proportion (stretch) of the column. default_hide False Default as a hidden/disabled column. default_sort False Default as a sorting column. width_stretch False Column will stretch. Preferable with horizontal scrolling disabled (default if table sizing policy is _SizingStretchSame or _SizingStretchProp). width_fixed False Column will not stretch. Preferable with horizontal scrolling enabled (default if table sizing policy is _SizingFixedFit and table is resizable). no_resize False Disable manual resizing. no_reorder False Disable manual reordering this column, this will also prevent other columns from crossing over this column. no_hide False Disable ability to hide/disable this column. no_clip False Disable clipping for this column. no_sort False Disable sorting for this column. no_sort_ascending False Disable ability to sort in the ascending direction. no_sort_descending False Disable ability to sort in the descending direction. no_header_width False Disable header text width contribution to automatic column width. prefer_sort_ascending True Make the initial sort direction Ascending when first sorting on this column (default). prefer_sort_descending False Make the initial sort direction Descending when first sorting on this column. indent_enabled False Use current Indent value when entering cell (default for column 0). indent_disable False Ignore current Indent value when entering cell (default for columns > 0). Indentation changes within the cell will still be honored. ====================== ============= ===========
DPG does not actually do any sorting for you. The table API is a more general purpose API and it is up to the library user to handle sorting. To sort a table based on user interaction, you must assign a callback to the table. This callback will be ran when a user tries to sort a table by clicking on the table's column headers.
.. code-block:: python
import dearpygui.dearpygui as dpg
dpg.create_context()
dpg.create_viewport()
dpg.setup_dearpygui()
def sort_callback(sender, sort_specs):
# sort_specs scenarios:
# 1. no sorting -> sort_specs == None
# 2. single sorting -> sort_specs == [[column_id, direction]]
# 3. multi sorting -> sort_specs == [[column_id, direction], [column_id, direction], ...]
#
# notes:
# 1. direction is ascending if == 1
# 2. direction is ascending if == -1
# no sorting case
if sort_specs is None: return
rows = dpg.get_item_children(sender, 1)
# create a list that can be sorted based on first cell
# value, keeping track of row and value used to sort
sortable_list = []
for row in rows:
first_cell = dpg.get_item_children(row, 1)[0]
sortable_list.append([row, dpg.get_value(first_cell)])
def _sorter(e):
return e[1]
sortable_list.sort(key=_sorter, reverse=sort_specs[0][1] < 0)
# create list of just sorted row ids
new_order = []
for pair in sortable_list:
new_order.append(pair[0])
dpg.reorder_items(sender, 1, new_order)
with dpg.window(label="Tutorial", width=500):
with dpg.table(header_row=True, borders_innerH=True, borders_outerH=True,
borders_innerV=True, borders_outerV=True, row_background=True,
sortable=True, callback=sort_callback):
dpg.add_table_column(label="One")
dpg.add_table_column(label="Two", no_sort=True)
for i in range(25):
with dpg.table_row():
dpg.add_input_int(label=" ", step=0, default_value=i)
dpg.add_text(f"Cell {i}, 1")
# main loop
dpg.show_viewport()
dpg.start_dearpygui()
dpg.destroy_context()
Under construction
You can make rows and/or cells selectable by adding a selectable to the table
and assigning a callback to it. Use a theme to control the hover style. The
span_columns option of the selectable is used to control whether
the row or the cell is selectable.
.. code-block:: python
import dearpygui.dearpygui as dpg
dpg.create_context()
with dpg.theme() as table_theme:
with dpg.theme_component(dpg.mvTable):
# dpg.add_theme_color(dpg.mvThemeCol_HeaderHovered, (255, 0, 0, 100), category=dpg.mvThemeCat_Core)
dpg.add_theme_color(dpg.mvThemeCol_HeaderActive, (0, 0, 0, 0), category=dpg.mvThemeCat_Core)
dpg.add_theme_color(dpg.mvThemeCol_Header, (0, 0, 0, 0), category=dpg.mvThemeCat_Core)
def clb_selectable(sender, app_data, user_data):
print(f"Row {user_data}")
with dpg.window(tag="Selectable Tables"):
with dpg.table(tag="SelectRows", header_row=True) as selectablerows:
dpg.add_table_column(label="First")
dpg.add_table_column(label="Second")
dpg.add_table_column(label="Third")
for i in range(15):
with dpg.table_row():
for j in range(3):
dpg.add_selectable(label=f"Row{i} Column{j}", span_columns=True, callback=clb_selectable, user_data=i)
dpg.bind_item_theme(selectablerows, table_theme)
with dpg.table(tag="SelectCells", header_row=True) as selectablecells:
dpg.add_table_column(label="First")
dpg.add_table_column(label="Second")
dpg.add_table_column(label="Third")
for i in range(15):
with dpg.table_row():
for j in range(3):
dpg.add_selectable(label=f"Row{i} Column{j}", callback=clb_selectable, user_data=(i,j))
dpg.bind_item_theme(selectablecells, table_theme)
dpg.create_viewport(width=800, height=600)
dpg.setup_dearpygui()
dpg.show_viewport()
dpg.start_dearpygui()
dpg.destroy_context()
Using a clipper can help performance with large tables.
Try using the example below with and with out clipping and see the effect on the framerate listed in metrics.
.. code-block:: python
import dearpygui.dearpygui as dpg
dpg.create_context()
def clipper_toggle(sender):
dpg.configure_item("table_clip", clipper=dpg.get_value(sender))
with dpg.window(label="Tutorial"):
dpg.add_checkbox(label="clipper", callback=clipper_toggle, default_value=True)
with dpg.table(header_row=False, tag="table_clip", clipper=True):
for i in range(5):
dpg.add_table_column()
for i in range(30000):
with dpg.table_row():
for j in range(5):
dpg.add_text(f"Row{i} Column{j}")
dpg.show_metrics()
dpg.create_viewport(title='Custom Title', width=800, height=600)
dpg.setup_dearpygui()
dpg.show_viewport()
dpg.start_dearpygui()
dpg.destroy_context()
Under construction
Under construction
Under construction
Under construction
Under construction
Under construction