Documentation Index Fetch the complete documentation index at: https://mintlify.com/ocornut/imgui/llms.txt
Use this file to discover all available pages before exploring further.
Dear ImGui’s table API provides powerful features for creating data grids with sorting, resizing, freezing, and more. Tables replaced the old Columns API starting from version 1.80.
Basic Tables
BeginTable() / EndTable()
Create a table:
IMGUI_API bool BeginTable ( const char * str_id, int columns, ImGuiTableFlags flags = 0 ,
const ImVec2 & outer_size = ImVec2 ( 0.0 f , 0.0 f ), float inner_width = 0.0 f );
IMGUI_API void EndTable ();
Unique identifier for the table
Table behavior flags (see below)
Outer size of the table container
Only call EndTable() if BeginTable() returns true!
Three Ways to Populate Tables
Most flexible - use in loops: if ( ImGui :: BeginTable ( "table1" , 3 )) {
for ( int row = 0 ; row < 4 ; row ++ ) {
ImGui :: TableNextRow ();
for ( int column = 0 ; column < 3 ; column ++ ) {
ImGui :: TableSetColumnIndex (column);
ImGui :: Text ( "Row %d Column %d " , row, column);
}
}
ImGui :: EndTable ();
}
More convenient for manual submission: if ( ImGui :: BeginTable ( "table2" , 3 )) {
for ( int row = 0 ; row < 4 ; row ++ ) {
ImGui :: TableNextRow ();
ImGui :: TableNextColumn ();
ImGui :: Text ( "Row %d " , row);
ImGui :: TableNextColumn ();
ImGui :: Text ( "Content" );
ImGui :: TableNextColumn ();
ImGui :: Text ( "123.456" );
}
ImGui :: EndTable ();
}
TableNextColumn() automatically wraps: if ( ImGui :: BeginTable ( "table3" , 3 )) {
for ( int item = 0 ; item < 14 ; item ++ ) {
ImGui :: TableNextColumn ();
ImGui :: Text ( "Item %d " , item);
}
ImGui :: EndTable ();
}
Table Rows
TableNextRow()
Advance to the next row:
IMGUI_API void TableNextRow (ImGuiTableRowFlags row_flags = 0 , float min_row_height = 0.0 f );
Optional row flags (e.g., ImGuiTableRowFlags_Headers)
Minimum row height (includes CellPadding.y * 2)
if ( ImGui :: BeginTable ( "table" , 2 )) {
// Regular row
ImGui :: TableNextRow ();
ImGui :: TableNextColumn (); ImGui :: Text ( "Normal" );
ImGui :: TableNextColumn (); ImGui :: Text ( "Row" );
// Tall row
ImGui :: TableNextRow ( 0 , 50.0 f );
ImGui :: TableNextColumn (); ImGui :: Text ( "Tall" );
ImGui :: TableNextColumn (); ImGui :: Text ( "Row" );
ImGui :: EndTable ();
}
Table Columns
TableSetupColumn()
Define column properties:
IMGUI_API void TableSetupColumn ( const char * label, ImGuiTableColumnFlags flags = 0 ,
float init_width_or_weight = 0.0 f , ImGuiID user_id = 0 );
Column label (used for headers)
Initial width (pixels) or weight (ratio)
if ( ImGui :: BeginTable ( "table" , 3 , ImGuiTableFlags_Resizable)) {
ImGui :: TableSetupColumn ( "Name" );
ImGui :: TableSetupColumn ( "Size" , ImGuiTableColumnFlags_WidthFixed, 100.0 f );
ImGui :: TableSetupColumn ( "Type" );
ImGui :: TableHeadersRow ();
for ( int row = 0 ; row < 5 ; row ++ ) {
ImGui :: TableNextRow ();
ImGui :: TableNextColumn (); ImGui :: Text ( "File %d " , row);
ImGui :: TableNextColumn (); ImGui :: Text ( " %d KB" , row * 10 );
ImGui :: TableNextColumn (); ImGui :: Text ( "Document" );
}
ImGui :: EndTable ();
}
Submit a row with header cells:
IMGUI_API void TableHeadersRow ();
if ( ImGui :: BeginTable ( "table" , 3 )) {
ImGui :: TableSetupColumn ( "ID" );
ImGui :: TableSetupColumn ( "Name" );
ImGui :: TableSetupColumn ( "Value" );
ImGui :: TableHeadersRow ();
// ... table contents ...
ImGui :: EndTable ();
}
Table Flags
Sizing Flags
// Default: columns are resizable
ImGuiTableFlags_Resizable
// Fit all columns within available width
ImGuiTableFlags_SizingFixedFit
// Columns stretch to fit available width
ImGuiTableFlags_SizingFixedSame
// Each column takes an equal portion
ImGuiTableFlags_SizingStretchProp
// All columns same width, stretch to fit
ImGuiTableFlags_SizingStretchSame
Border Flags
All Borders
Selective Borders
// All borders
ImGuiTableFlags_Borders
// Equivalent to:
ImGuiTableFlags_BordersInnerV | ImGuiTableFlags_BordersOuterV |
ImGuiTableFlags_BordersInnerH | ImGuiTableFlags_BordersOuterH
// Enable horizontal scrolling
ImGuiTableFlags_ScrollX
// Enable vertical scrolling
ImGuiTableFlags_ScrollY
Row Flags
// Alternating row background colors
ImGuiTableFlags_RowBg
// Make rows selectable
ImGuiTableFlags_RowClickable
Sorting Flags
// Enable sorting (single column)
ImGuiTableFlags_Sortable
// Allow sorting by multiple columns (Shift+Click)
ImGuiTableFlags_SortMulti
// Allow removing sort by Ctrl+clicking headers
ImGuiTableFlags_SortTristate
Create tables with frozen headers and scrolling:
if ( ImGui :: BeginTable ( "table" , 3 ,
ImGuiTableFlags_ScrollY | ImGuiTableFlags_RowBg | ImGuiTableFlags_Borders,
ImVec2 ( 0 , 300 ))) {
ImGui :: TableSetupColumn ( "ID" );
ImGui :: TableSetupColumn ( "Name" );
ImGui :: TableSetupColumn ( "Value" );
ImGui :: TableHeadersRow ();
for ( int row = 0 ; row < 100 ; row ++ ) {
ImGui :: TableNextRow ();
ImGui :: TableNextColumn (); ImGui :: Text ( " %04d " , row);
ImGui :: TableNextColumn (); ImGui :: Text ( "Item %d " , row);
ImGui :: TableNextColumn (); ImGui :: Text ( " %d " , row * 100 );
}
ImGui :: EndTable ();
}
Freeze columns and rows:
IMGUI_API void TableSetupScrollFreeze ( int cols, int rows);
if ( ImGui :: BeginTable ( "table" , 4 , ImGuiTableFlags_ScrollX | ImGuiTableFlags_ScrollY)) {
ImGui :: TableSetupScrollFreeze ( 1 , 1 ); // Freeze first column and first row
ImGui :: TableSetupColumn ( "ID" );
ImGui :: TableSetupColumn ( "Name" );
ImGui :: TableSetupColumn ( "Age" );
ImGui :: TableSetupColumn ( "City" );
ImGui :: TableHeadersRow ();
// ... table contents ...
ImGui :: EndTable ();
}
Sorting
TableGetSortSpecs()
Get sorting specifications:
IMGUI_API ImGuiTableSortSpecs * TableGetSortSpecs ();
struct MyItem {
int id;
const char * name;
int value;
};
static ImVector < MyItem > items;
if ( ImGui :: BeginTable ( "table" , 3 , ImGuiTableFlags_Sortable | ImGuiTableFlags_RowBg)) {
ImGui :: TableSetupColumn ( "ID" , ImGuiTableColumnFlags_DefaultSort);
ImGui :: TableSetupColumn ( "Name" );
ImGui :: TableSetupColumn ( "Value" );
ImGui :: TableHeadersRow ();
// Get sort specs
if (ImGuiTableSortSpecs * sort_specs = ImGui :: TableGetSortSpecs ()) {
if ( sort_specs -> SpecsDirty ) {
// Sort your data
// sort_specs->Specs[0].ColumnUserID
// sort_specs->Specs[0].ColumnIndex
// sort_specs->Specs[0].SortDirection (ImGuiSortDirection_Ascending/Descending)
// ... perform sort ...
sort_specs -> SpecsDirty = false ;
}
}
// Display items
for ( const MyItem & item : items) {
ImGui :: TableNextRow ();
ImGui :: TableNextColumn (); ImGui :: Text ( " %d " , item . id );
ImGui :: TableNextColumn (); ImGui :: Text ( " %s " , item . name );
ImGui :: TableNextColumn (); ImGui :: Text ( " %d " , item . value );
}
ImGui :: EndTable ();
}
Column Flags
Width
// Auto-sizing width
ImGuiTableColumnFlags_WidthStretch // Default
// Fixed width
ImGuiTableColumnFlags_WidthFixed
Resizing
// User cannot resize this column
ImGuiTableColumnFlags_NoResize
// Double-click to auto-fit
ImGuiTableColumnFlags_NoAutoResize
Sorting
// Default sort direction
ImGuiTableColumnFlags_DefaultSort
// User cannot sort this column
ImGuiTableColumnFlags_NoSort
// Prefer ascending sort
ImGuiTableColumnFlags_PreferSortAscending
// Prefer descending sort
ImGuiTableColumnFlags_PreferSortDescending
Visibility
// Start hidden
ImGuiTableColumnFlags_DefaultHide
// Disable ability to hide column
ImGuiTableColumnFlags_NoHide
Advanced Features
Enable right-click column menu:
ImGui :: BeginTable ( "table" , 3 , ImGuiTableFlags_ContextMenuInBody);
Hideable Columns
if ( ImGui :: BeginTable ( "table" , 4 , ImGuiTableFlags_Hideable)) {
ImGui :: TableSetupColumn ( "Column 1" );
ImGui :: TableSetupColumn ( "Column 2" , ImGuiTableColumnFlags_DefaultHide);
ImGui :: TableSetupColumn ( "Column 3" );
ImGui :: TableSetupColumn ( "Column 4" );
ImGui :: TableHeadersRow ();
// Right-click on headers to show/hide columns
// ...
ImGui :: EndTable ();
}
Reorderable Columns
ImGui :: BeginTable ( "table" , 3 , ImGuiTableFlags_Reorderable);
Complete Example
void ShowTableDemo () {
ImGui :: Begin ( "Table Demo" );
// Basic table with borders
if ( ImGui :: BeginTable ( "table1" , 3 , ImGuiTableFlags_Borders | ImGuiTableFlags_RowBg)) {
ImGui :: TableSetupColumn ( "Name" );
ImGui :: TableSetupColumn ( "Age" );
ImGui :: TableSetupColumn ( "City" );
ImGui :: TableHeadersRow ();
ImGui :: TableNextRow ();
ImGui :: TableNextColumn (); ImGui :: Text ( "Alice" );
ImGui :: TableNextColumn (); ImGui :: Text ( "25" );
ImGui :: TableNextColumn (); ImGui :: Text ( "New York" );
ImGui :: TableNextRow ();
ImGui :: TableNextColumn (); ImGui :: Text ( "Bob" );
ImGui :: TableNextColumn (); ImGui :: Text ( "30" );
ImGui :: TableNextColumn (); ImGui :: Text ( "London" );
ImGui :: TableNextRow ();
ImGui :: TableNextColumn (); ImGui :: Text ( "Charlie" );
ImGui :: TableNextColumn (); ImGui :: Text ( "35" );
ImGui :: TableNextColumn (); ImGui :: Text ( "Tokyo" );
ImGui :: EndTable ();
}
ImGui :: Spacing ();
ImGui :: Separator ();
ImGui :: Spacing ();
// Scrolling table with frozen header
if ( ImGui :: BeginTable ( "table2" , 4 ,
ImGuiTableFlags_ScrollY | ImGuiTableFlags_RowBg |
ImGuiTableFlags_Borders | ImGuiTableFlags_Resizable,
ImVec2 ( 0 , 200 ))) {
ImGui :: TableSetupScrollFreeze ( 0 , 1 ); // Freeze header row
ImGui :: TableSetupColumn ( "ID" );
ImGui :: TableSetupColumn ( "Name" );
ImGui :: TableSetupColumn ( "Value" );
ImGui :: TableSetupColumn ( "Status" );
ImGui :: TableHeadersRow ();
for ( int row = 0 ; row < 50 ; row ++ ) {
ImGui :: TableNextRow ();
ImGui :: TableNextColumn (); ImGui :: Text ( " %04d " , row);
ImGui :: TableNextColumn (); ImGui :: Text ( "Item %d " , row);
ImGui :: TableNextColumn (); ImGui :: Text ( " %d " , row * 100 );
ImGui :: TableNextColumn (); ImGui :: Text (row % 2 ? "Active" : "Inactive" );
}
ImGui :: EndTable ();
}
ImGui :: End ();
}
For very large tables, use ImGuiListClipper:
if ( ImGui :: BeginTable ( "large_table" , 3 , ImGuiTableFlags_ScrollY)) {
ImGui :: TableSetupColumn ( "ID" );
ImGui :: TableSetupColumn ( "Name" );
ImGui :: TableSetupColumn ( "Value" );
ImGui :: TableHeadersRow ();
ImGuiListClipper clipper;
clipper . Begin ( 10000 ); // 10,000 items
while ( clipper . Step ()) {
for ( int row = clipper . DisplayStart ; row < clipper . DisplayEnd ; row ++ ) {
ImGui :: TableNextRow ();
ImGui :: TableNextColumn (); ImGui :: Text ( " %d " , row);
ImGui :: TableNextColumn (); ImGui :: Text ( "Item %d " , row);
ImGui :: TableNextColumn (); ImGui :: Text ( " %d " , row * 10 );
}
}
ImGui :: EndTable ();
}
Best Practices
Always call EndTable() only if BeginTable() returns true.
Use ImGuiTableFlags_SizingStretchProp for responsive tables that adapt to window size.
Call TableSetupColumn() before TableHeadersRow() to define column properties and labels.
Combine ImGuiTableFlags_ScrollY with TableSetupScrollFreeze(0, 1) to keep headers visible while scrolling.